This example shares the specific implementation code for reading user login and uploading server for your reference. The specific content is as follows
The client runs on a server that provides the user with unix services. Used to read and collect the upstream and downstream information of users on the server, pair and organize them, and then send them to the server for summary.
Specific implementation code:
1. DMSServer.java
package com.dms; import java.io.BufferedReader;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.concurrent.BlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.LinkedBlockingQueue; import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader; /** * DMS server, used to receive * pairing logs sent by each client and save them in a local file* @author Administrator * */public class DMSServer { //Property definition//ServerSocket private ServerSocket server used to receive the server connected to the client; //Thread pool used to manage threads that handle client requests private ExecutorService threadPool; //Save all files sent by clients to pair logs private File serverLogFile; //Message queue private BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>(); public DMSserver() throws Exception{ try { System.out.println("The server is initializing..."); //1 Parse the configuration file server-config.xml Map<String,String> config = loadConfig(); //2 Initialize the attribute init(config); System.out.println("Server initialization completed..."); } catch (Exception e) { System.out.println("Initialization failed!"); throw e; } } /** * The first step in initializing the constructor method is to parse the configuration file* @return The returned Map is saved in each item of the configuration file, where key: the name of the tag, * value is the text in the middle of the tag* @throws Exception */ private Map<String,String> loadConfig() throws Exception{ try { SAXReader reader = new SAXReader(); Document doc = reader.read(new File("server-config.xml")); Element root = doc.getRootElement(); Map<String,String> config = new HashMap<String,String>(); /* * Get all sub-tags in the <config> tag* and save the name of each sub-tag as the key, and the * text in the middle is value in the Map collection*/ List<Element> list = root.elements(); for(Element e : list){ String key = e.getName(); String value = e.getTextTrim(); config.put(key, value); } return config; } catch (Exception e) { System.out.println("Resolve configuration file exception!"); e.printStackTrace(); throw e; } } /** * The second step of initializing the constructor method is to initialize the attribute according to the configuration item* @param config * @throws Exception */ private void init(Map<String,String> config) throws Exception{ /* * Initialize the attribute with <logrecfile> in the configuration file: serverLogFile * Initialize the property: threadPool with <threadsum> in the configuration file, where a fixed-size thread pool is created. This value is used as the number of thread pool threads* Initialize the property with the <serverport> in the configuration file: server, here this value is the server port of ServerSocket*/ this.server = new ServerSocket( Integer.parseInt(config.get("serverport"))) ); this.serverLogFile = new File( config.get("logrecfile") ); this.threadPool = Executors.newFixedThreadPool( Integer.parseInt(config.get("threadsum")) ); } /** * Method to start working on the server* @throws Exception */ public void start() throws Exception{ /* * Implementation requirements: * First start a thread separately to run the SaveLogHandler * This task is to save all pairing logs* and then start listening to the server ports loop. Once a client is connected, * instantiate a ClientHander, and then hand over the task to the thread pool* to assign threads to handle interaction with the client. * */ try { System.out.println("The server starts working..."); SaveLogHandler slh=new SaveLogHandler(); new Thread(slh).start(); while(true){ Socket socket=server.accept(); threadPool.execute(new ClientHandler(socket)); } } catch (Exception e) { e.printStackTrace(); throw e; } } public static void main(String[] args) { try { DMSServer server = new DMSServer(); server.start(); } catch (Exception e) { System.out.println("Station failed to start the server!"); } } } /** * This thread is responsible for fetching each paired log from the message queue, * and saving it into the serverLogFile file* @author Administrator * */ private class SaveLogHandler implements Runnable{ public void run(){ PrintWriter pw = null; try { pw = new PrintWriter( new FileOutputStream( serverLogFile,true ) ); while(true){ if(messageQueue.size()>0){ pw.println(messageQueue.poll()); }else{ pw.flush(); Thread.sleep(500); } } } catch (Exception e) { e.printStackTrace(); } finally{ if(pw != null){ pw.close(); } } } } } /** * Handle a specified client request* @author Administrator * */ private class ClientHandler implements Runnable{ private Socket socket; public ClientHandler(Socket socket){ this.socket = socket; } public void run(){ /* * Idea: * First receive all paired logs sent by the client, * until "OVER", then save these paired* logs to the local file, and reply to the client * "OK" * Execute steps: * 1: Create an output stream through Socket to send a response to the client * 2: Create an input stream through Socket, read the logs sent by the client * 3: Read each line of string sent by the client, and * first determine whether it is the string "OVER". If not, it is a paired log, and save it to the local file. If so, * stop reading. * 4: Reply to the client "OK" after successfully reading all logs */ PrintWriter pw = null; try { //1 pw = new PrintWriter( new OutputStreamWriter( socket.getOutputStream(),"UTF-8" ) ); //2 BufferedReader br = new BufferedReader( new InputStreamReader( socket.getInputStream(),"UTF-8" ) ); //3 String message = null; while((message = br.readLine())!=null){ if("OVER".equals(message)){ break; } //Write the log to a file to save messageQueue.offer(message); } //4 pw.println("OK"); pw.flush(); } catch (Exception e) { e.printStackTrace(); pw.println("ERROR"); pw.flush(); } finally{ try { //Disconnect from the client to release the resource socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } } } } } } } } } 2. DMSClient.java
package com.dms; import java.io.BufferedReader;import java.io.File;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.io.RandomAccessFile;import java.net.Socket;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Map.Entry;import java.util.Set; import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader; import com.dms.bo.LogData;import com.dms.bo.LogRec; /** * This client runs on the server that provides users with unix services. * Used to read and collect the upstream and downstream information of users on the server, and * pair and sort them out and send them to the server for summary. * @author Administrator * */public class DMSClient { //Attribute definition//Step 1: Parse the required properties of the log//Unix system log file private File logFile; //Save the file of the parsed log private File textLogFile; //Bookmark file private File lastPositionFile; //Number of entries for each parsing log private int batch; //Step 2: Pair the attributes of the log//Save the file private File logRecFile; //Save the file private File loginLogFile; //Step 3: Parse the attributes of the log//Server address private String serverHost; //Server port private int serverPort; /** * Constructor method, used to initialize the client* @throws Exception */ public DMSClient() throws Exception{ try { //1 parse the configuration file config.xml Map<String,String> config = loadConfig(); //Piling System.out.println(config); //2 Initialize the attribute init(config); } catch (Exception e) { System.out.println("Initialization failed!"); throw e; } } /** * Initialize the second step of constructor method, initialize the attributes according to the configuration item* @param config * @throws Exception */ private void init(Map<String,String> config) throws Exception{ try { logFile = new File( config.get("logfile") ); textLogFile = new File( config.get("textlogfile") ); lastPositionFile = new File( config.get("lastpositionfile") ); batch = Integer.parseInt( config.get("batch") ); logRecFile = new File( config.get("logrecfile") ); loginLogFile = new File( config.get("loginlogfile") ); serverHost = config.get("serverhost"); serverPort = Integer.parseInt( config.get("serverport") ); } catch (Exception e) { System.out.println("Initialization property failed!"); e.printStackTrace(); throw e; } } /** * The first step in the initialization of the constructor method is to parse the configuration file* @return The returned Map is saved in each item of the configuration file, where key: the name of the tag, * value is the text in the middle of the tag * @throws Exception */ private Map<String,String> loadConfig() throws Exception{ try { SAXReader reader = new SAXReader(); Document doc = reader.read(new File("config.xml")); Element root = doc.getRootElement(); Map<String,String> config = new HashMap<String,String>(); /* * Get all sub-tags in the <config> tag* and use the name of each sub-tag as the key, the * in the middle Text is stored in the Map collection as value*/ List<Element> list = root.elements(); for(Element e : list){ String key = e.getName(); String value = e.getTextTrim(); config.put(key, value); } return config; } catch (Exception e) { System.out.println("Parse configuration file exception!"); e.printStackTrace(); throw e; } } /** * Method for the client to start working* Three steps of the loop: * 1: Parsing the log* 2: Pairing the log* 3: Send the log*/ public void start(){ parseLogs(); matchLogs(); sendLogs();// while(true){// // parse log// if(!parseLogs()){// continue;// }// // pairing log/// if(!matchLogs()){// continue;// }// // Send log// sendLogs();// } } /** * Step 3: Send log* @return true: Send successfully* false: Send failed*/ private boolean sendLogs(){ /* * Implementation idea: * Read all paired logs in the logRecFile file* and connect to the server and send it over, if the server* If you receive all of them, you can delete the file, which means that the sending* is completed. * Implementation steps: * 1: The logRecFile file must exist* 2: Read out and store all paired logs into a collection* Wait for sending* 3: Connect to the server through Socket* 4: Create output stream* 5: Send all paired logs in sequence to the server in line* 6: Send a single string "OVER" to indicate that all logs* has been sent* 7: Create input stream* 8: Read the response string sent back by the server* 9: If the response string is "OK", it means that the server is normal* has received all logs, and then the logRecFile * file can be deleted and returned true means that the sending is completed. * */ Socket socket = null; try { //1 if(!logRecFile.exists()){ System.out.println(logRecFile+"Not exist!"); return false; } //2 List<String> matches = IOUtil.loadLogRec(logRecFile); //3 socket = new Socket(serverHost,serverPort); //4 PrintWriter pw = new PrintWriter( new OutputStreamWriter( socket.getOutputStream(),"UTF-8" ) ); //5 for(String log : matches){ pw.println(log); } //6 pw.println("OVER"); pw.flush(); //7 BufferedReader br = new BufferedReader( new InputStreamReader( socket.getInputStream(),"UTF-8" ) ); //8 String response = br.readLine(); //9 if("OK".equals(response)){ logRecFile.delete(); return true; }else{ System.out.println("Send log failed!"); return false; } } catch (Exception e) { System.out.println("Send log failed!"); e.printStackTrace(); } finally{ if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } return false; } /** * Step 2: Pair the log* @return true: Pairing successfully* false: Pairing failed*/ private boolean matchLogs(){ /* * Implementation idea: * Read all the new log parsed in the first step with the login log that was the last paired successfully*, and then follow user, * The same pid, one is 7 and the other is 8 for pairing. * As long as you can find a type 8, you can find a login log that can be paired with *. * * Implementation steps: * 1: Necessary judgment* 1.1: Whether logRecFile exists. If it exists, it will no longer be * New pairing work will be performed to avoid overwrite. * 1.2: The textLogFile file must exist. * 2: Read textLogFile and read the logs and * to the collection. (Several LogData instances) * 3: If the loginLogFile file exists, it means * There is a log that was not paired successfully last time, and it is also read * and saved in the collection waiting to be paired together* 4: Pairing work* 4.1: Create a collection to save all paired logs* 4.2: Create two maps to save login and logout logs* 4.3: traverse all logs to be paired and save them into two maps according to login and logout* * where key:user,pid * value:LogData instance* 4.4: traverse the logout map, and find the corresponding login log in the login map according to the key * of each logout log, and * save the paired log in the set of paired logs. And delete the login log in the paired log* from the login map. In this way, ** you should only have no pairing left when you log in to the map. * 5: Write paired logs to logRecFile* 6: Write all unpaired logs to loginLogFile* 7: Delete textLogFile file* 8: Return true, indicating that pairing is completed* */ try { //1 //1.1 if(logRecFile.exists()){ return true; } //1.2 if(!textLogFile.exists()){ System.out.println(textLogFile+"Not exist!"); return false; } //2 List<LogData> list = IOUtil.loadLogData(textLogFile); //3 if(loginLogFile.exists()){ list.addAll( IOUtil.loadLogData(loginLogFile) ); } //4 //4.1 List<LogRec> matches = new ArrayList<LogRec>(); //4.2 Map<String,LogData> loginMap = new HashMap<String,LogData>(); Map<String,LogData> logoutMap = new HashMap<String,LogData>(); //4.3 for(LogData logData: list){ String key = logData.getUser()+","+ logData.getPid(); if(logData.getType()==LogData.TYPE_LOGIN){ loginMap.put(key, logData); }else if(logData.getType()==LogData.TYPE_LOGOUT){ logoutMap.put(key, logData); } } //4.4 Set<Entry<String,LogData>> entrySet = logoutMap.entrySet(); for(Entry<String,LogData> e : entrySet){ LogData logout = e.getValue(); LogData login = loginMap.remove(e.getKey()); LogRec logRec = new LogRec(login,logout); matches.add(logRec); } //5 IOUtil.saveCollection(matches, logRecFile); //6 IOUtil.saveCollection( loginMap.values(),loginLogFile ); //7 textLogFile.delete(); //8 return true; } catch (Exception e) { System.out.println("Pairing log failed!"); e.printStackTrace(); } return false; } /** * Step 1: parse the log* @return true: parse successful* false: parse failed*/ private boolean parseLogs(){ /* * Implementation idea: * Loop reading batch logs, then parse * 5 information in each log, and finally form a string, write it to the textLogFile file in * behavior units* * Implementation steps: * 1: Necessary judgment work* 1.1: In order to avoid the parsed log not being used yet, and * the first step repeats execution, causing the previous log to be overwritten*, you need to judge here. If you save the parsed log* The log file exists, and the first step will no longer be executed. * This log file will be deleted after the second step is paired. * 1.2: The logFile file must exist (wtmpx file) * 1.3: Is there still a log that can be parsed* 2: Create a RandomAccessFile to read the logFile * 3: Move the pointer to the last read position, prepare * Start a new parsing work* 4: Parsing work* 4.1: Create a List collection to save each log after parsing (LogData instance) * 4.2: Loop batch times to parse * 5 contents in each log (user,pid,type,time,host) * and save it with a LogData instance, and then save * the LogData instance into the collection* 5: Save all logs in the collection in behavior units to * textLogFile * 6: Save bookmark information* 7: Return true, indicating that the work is completed* */ RandomAccessFile raf = null; try { //1 //1.1 if(textLogFile.exists()){ return true; } //1.2 if(!logFile.exists()){ System.out.println(logFile+"Not exist!"); return false; } //1.3 long lastPosition = hasLogs(); //Piling// System.out.println(// "lastPosition:"+lastPosition// ); if(lastPosition<0){ System.out.println("No logs can be parsed!"); return false; } //2 raf = new RandomAccessFile(logFile,"r"); //3 raf.seek(lastPosition); //4 List<LogData> list = new ArrayList<LogData>(); for(int i=0;i<batch;i++){ //Before each parsing, determine whether there are still logs that can be parsed if(logFile.length()-lastPosition <LogData.LOG_LENGTH ){ break; } //Parse user raf.seek(lastPosition+LogData.USER_OFFSET); String user = IOUtil.readString( raf, LogData.USER_LENGTH ).trim(); //Parse PID raf.seek(lastPosition+LogData.PID_OFFSET); int pid = raf.readInt(); //Parse TYPE raf.seek(lastPosition+LogData.TYPE_OFFSET); short type = raf.readShort(); //Parse TIME raf.seek(lastPosition+LogData.TIME_OFFSET); int time = raf.readInt(); //Paste HOST raf.seek(lastPosition+LogData.HOST_OFFSET); String host = IOUtil.readString( raf, LogData.HOST_LENGTH ).trim(); LogData log = new LogData(user, pid, type, time, host); list.add(log); //Piling// System.out.println(log); //Upload a log, update lastPosition lastPosition = raf.getFilePointer(); } //5 IOUtil.saveCollection(list, textLogFile); //6 Save the bookmark file IOUtil.saveLong( lastPosition, lastPositionFile); //7 return true; } catch (Exception e) { System.out.println("Passing log failed!"); e.printStackTrace(); } finally{ if(raf != null){ try { raf.close(); } catch (IOException e) { e.printStackTrace(); } } return false; } /** * The first step is to parse a link in the log. * According to the location of the bookmark file record, determine whether there is still * log to parse. If there is, the last position* will be returned. If there is no, return -1. * @return */ private long hasLogs(){ try { /* * If lastPositionFile does not exist, it means * has never been parsed, so you can parse from scratch*/ if(!lastPositionFile.exists()){ return 0; } long lastPosition = IOUtil.readLong(lastPositionFile); if(logFile.length()-lastPosition >=LogData.LOG_LENGTH){ return lastPosition; } } catch (Exception e) { e.printStackTrace(); } return -1; } public static void main(String[] args) { try { DMSClient client = new DMSClient(); client.start(); } catch (Exception e) { System.out.println("Client run failed!"); } }} 3. IOUtil.java
package com.dms; import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.io.RandomAccessFile;import java.util.ArrayList;import java.util.Collection;import java.util.List;import com.dms.bo.LogData; /** * This class is a tool class that is responsible for client IO operations* @author Administrator * */public class IOUtil { /** * Read each line of string from the given file (pair log) * and save a collection to return * @param file * @return * @throws Exception */ public static List<String> loadLogRec(File file) throws Exception{ BufferedReader br = null; try { br = new BufferedReader( new InputStreamReader( new FileInputStream( file ) ) ); List<String> list = new ArrayList<String>(); String line = null; while((line = br.readLine())!=null){ list.add(line); } return list; } catch (Exception e) { e.printStackTrace(); throw e; } finally{ if(br != null){ br.close(); } } } /** * Read each paired log from the given file and save it into * a collection and then return. * @param file * @return * @throws Exception */ public static List<LogData> loadLogData(File file) throws Exception{ BufferedReader br = null; try { br = new BufferedReader( new InputStreamReader( new FileInputStream( file ) ) ); List<LogData> list = new ArrayList<LogData>(); String line = null; while((line = br.readLine())!=null){ LogData logData = new LogData(line); list.add(logData); } return list; } catch (Exception e) { e.printStackTrace(); throw e; } finally{ if(br!=null){ br.close(); } } } /** * Write the specified long value into the first line of the given file as a string* @param l * @param file * @throws Exception */ public static void saveLong( long lon,File file) throws Exception{ PrintWriter pw = null; try { pw = new PrintWriter(file); pw.println(lon); } catch (Exception e) { e.printStackTrace(); throw e; } finally{ if(pw != null){ pw.close(); } } } } /** * Write the string returned by the toString method of each element in the collection to the specified file in behavior units. * @param c * @param file * @throws Exception */ public static void saveCollection( Collection c,File file) throws Exception{ PrintWriter pw = null; try { pw = new PrintWriter(file); for(Object o : c){ pw.println(o); } } catch (Exception e) { e.printStackTrace(); throw e; } finally{ if(pw != null){ pw.close(); } } } /** * Start continuous from the current position of the given RandomAccessFile* Read length bytes and convert them into a string and return * @param raf * @param length * @return * @throws Exception */ public static String readString( RandomAccessFile raf,int length) throws Exception{ try { byte[] data = new byte[length]; raf.read(data); return new String(data,"ISO8859-1"); } catch (Exception e) { e.printStackTrace(); throw e; } } /** * Read the first line of string from the given file and then * Return * @param file * @return * @throws Exception */ public static long readLong(File file) throws Exception{ BufferedReader br = null; try { br = new BufferedReader( new InputStreamReader( new FileInputStream( file ) ) ); String line = br.readLine(); return Long.parseLong(line); } catch (Exception e) { e.printStackTrace(); throw e; } finally{ if(br != null){ br.close(); } } }}
4. config.xml
<?xml version="1.0" encoding="UTF-8"?><config> <!-- unix system log file name --> <logfile>wtmpx</logfile> <!-- save the resolved log file name --> <textlogfile>log.txt</textlogfile> <!-- Bookmark file name --> <lastpositionfile>last-position.txt</lastpositionfile> <!-- Number of entries per parsed log--> <batch>10</batch> <!-- Paired log file name --> <logrecfile>logrec.txt</logrecfile> <!-- Unpaired log file name --> <loginlogfile>login.txt</loginlogfile> <!-- Unpaired log file name --> <loginlogfile>login.txt</loginlogfile> <!-- Server address --> <serverhost>localhost</serverhost> <!-- Server port --> <serverport>8088</serverport></config>
5. server-config.xml
<?xml version="1.0" encoding="UTF-8"?><config> <!-- File name of the server that saves the paired log file --> <logrecfile>server-logs.txt</logrecfile> <!-- Number of thread pool threads--> <threadsum>30</threadsum> <!-- Server port--> <serverport>8088</serverport></config>
The above is all about this article, I hope it will be helpful to everyone's learning.