本文实例为大家分享了读取用户登入出日志并上传服务端的具体实现代码,供大家参考,具体内容如下
该客户端运行在给用户提供unix服务的服务器上。用来读取并收集该服务器上用户的上下线信息,并进行配对整理后发送给服务端汇总。
具体实现代码:
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服务端,用来接收每个客户端发送过来的
* 配对日志并保存在本地文件中
* @author Administrator
*
*/
public class DMSServer {
//属性定义
//用来接收客户端连接的服务端的ServerSocket
private ServerSocket server;
//用来管理处理客户端请求的线程的线程池
private ExecutorService threadPool;
//保存所有客户端发送过来配对日志的文件
private File serverLogFile;
//消息队列
private BlockingQueue messageQueue = new LinkedBlockingQueue();
public DMSServer() throws Exception{
try {
System.out.println("服务端正在初始化...");
//1 解析配置文件server-config.xml
Map config = loadConfig();
//2 根据配置文件内容初始化属性
init(config);
System.out.println("服务端初始化完毕...");
} catch (Exception e) {
System.out.println("初始化服务端失败!");
throw e;
}
}
/**
* 构造方法初始化第一步,解析配置文件
* @return 返回的Map中保存的是配置文件中的
* 每一条内容,其中key:标签的名字,
* value为标签中间的文本
* @throws Exception
*/
private Map loadConfig() throws Exception{
try {
SAXReader reader = new SAXReader();
Document doc
= reader.read(new File("server-config.xml"));
Element root = doc.getRootElement();
Map config
= new HashMap();
/*
* 获取标签中的所有子标签
* 并将每一个子标签的名字作为key,中间的
* 文本作为value存入Map集合
*/
List 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("解析配置文件异常!");
e.printStackTrace();
throw e;
}
}
/**
* 构造方法初始化第二步,根据配置项初始化属性
* @param config
* @throws Exception
*/
private void init(Map config) throws Exception{
/*
* 用配置文件中的初始化属性:serverLogFile
* 用配置文件中的初始化属性:threadPool,这里创建固定大小线程池。该值作为线程池线程数量
* 用配置文件中的初始化属性:server,这里这个值为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"))
);
}
/**
* 服务端开始工作的方法
* @throws Exception
*/
public void start() throws Exception{
/*
* 实现要求:
* 首先单独启动一个线程,用来运行SaveLogHandler
* 这个任务,目的是保存所有配对日志
* 然后开始循环监听服务端端口,一旦一个客户端连接了,
* 就实例化一个ClientHander,然后将该任务交给线程池
* 使其分配线程来处理与该客户端的交互。
*
*/
try {
System.out.println("服务端开始工作...");
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("启动服务端失败!");
}
}
/**
* 该线程负责从消息队列中取出每一条配对日志,
* 并存入到serverLogFile文件
* @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);
}
}