学了一个月java了,第一次独立写wtmpx文件的解析,完成了大概一整个从服务器下载,解析,上传,保存到mysql数据库,保存到xml文件的过程。
因为是初学,所有写了好多奇怪的方法,用来练习学过的东西,写的不是很好,由于时间不允许,只能先这样,以后有时间再做修改了,贴一些自己觉得重要的代码,以便自己忘了可以复习一下
server:
package com.alex;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.alex.dao.BaseDAO;
import com.alex.util.FileIO;
import com.alex.util.MD5Util;
/**
* 加入线程池,可以接受多个client
*
*
*/
public class Server03 {
private int port;
private String serverpath;
private ServerSocket serverSocket;
//加入线程池,完成线程的重新调度
private ExecutorService threadPool;
//保存login_out.txt文见地址
private String login_outpath;
public Server03() {
BaseDAO base=new BaseDAO();
port = Integer.parseInt(base.getValue("port"));
serverpath = base.getValue("serverpath");
//设计线程池包含5个线程
threadPool=Executors.newFixedThreadPool(5);
login_outpath=base.getValue("login_outpathserver");
try {
serverSocket=new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server03 server=new Server03();
server.start();
}
public void start(){
while(true){
try {
//1.创建连接
System.out.println("等待客户连接。。。");
Socket socket=serverSocket.accept();
System.out.println("客户端连接成功");
//启动一个线程来完成客户端的交互
ClientHandler handler=new ClientHandler(socket);
threadPool.execute(handler);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class ClientHandler implements Runnable{
private Socket socket;
public ClientHandler(Socket socket){
this.socket=socket;
}
@Override
public void run() {
try{
BufferedInputStream bis=null;
OutputStream os=socket.getOutputStream();
BufferedOutputStream bos=new BufferedOutputStream(os);
InputStream is=socket.getInputStream();
bis=new BufferedInputStream(is);
//2返送MD5值
System.out.println("-------------------");
System.out.println("server发送md5值开始");
String md5=MD5Util.getHash(serverpath);
System.out.println("MD5:"+md5);
byte[] buf=md5.getBytes();
bos.write(buf);
bos.flush();
System.out.println("server发送md5值结束");
System.out.println("-------------------");
//发送文件
if(bis.read()==0){
System.out.println("server开始发送文件");
FileIO.sendFile(serverpath,bos);
System.out.println("server文件发送完毕");
}
/**
* 为什么这里读完文件之后,fluse之后,client还在等在文件流呢?
* 因为你都文件的时候,是从文件读取,读到最后有-1返回,文件读写会正常结束
* 但是文件写入输出流,client接受文件时,根本得不到-1,因为server根本就
* 没有写入-1给输出流,这下client悲剧了,它读不到-1,就一直在等啊等,
* 死循环了,做法是发送文件长度给client或者主动关闭server的OutputStream流。
*/
socket.shutdownOutput();
System.out.println("文件验证结束");
}catch(Exception e){
e.printStackTrace();
}finally{
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
client:
package com.alex;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;
import com.alex.dao.BaseDAO;
import com.alex.util.FileIO;
import com.alex.util.MD5Util;
public class Client {
private String ip;
private int port;
private String clientpath;
private String logpath;
private String position;
private String login_outpath;
public Client() {
BaseDAO base=new BaseDAO();
ip = base.getValue("ip");
port =Integer.parseInt(base.getValue("port"));
clientpath = base.getValue("clientpath");
logpath=base.getValue("logpath");
position=base.getValue("positionpath");
login_outpath=base.getValue("login_outpath");
}
public static void main(String[] args){
Client client=new Client();
client.start();
}
public void start(){
Socket socket=null;
boolean stop=false;
BufferedOutputStream bos=null;
try {
System.out.println("IP地址:"+ip+"Port号:"+port);
//1.创建连接
socket=new Socket(ip,port);
InputStream is=socket.getInputStream();
BufferedInputStream bis=new BufferedInputStream(is);
OutputStream os=socket.getOutputStream();
bos=new BufferedOutputStream(os);
//2.获得MD5值
byte[] buf=new byte[32];
bis.read(buf);
String serverMd5=new String(buf);
System.out.println(serverMd5);
System.out.println("开始计算client文件MD5");
try {
String clientMd5=MD5Util.getHash(clientpath);
System.out.println("ClientMd5:"+clientMd5);
//3.比较MD5
if(serverMd5.equals(clientMd5)){
System.out.println("文件已存在,谢谢");
}else{
//4.返回0,等待服务器发送文件过来。
bos.write(0);
bos.flush();
stop=FileIO.saveFile(clientpath, bis);
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//读取wptmx文件,生成log.txt文件
try {
FileIO.readFile(clientpath,logpath,position);
// //解析生成的log.txt文件,生成loginMap和logoutMap文件
} catch (IOException e) {
e.printStackTrace();
}
// if(stop){
// try {
// socket=new Socket(ip,port);
// OutputStream os=socket.getOutputStream();
// System.out.println("文件保存完毕,返回1给server");
// os.write(1);
// os.flush();
// } catch (UnknownHostException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// }finally{
// try {
// socket.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
//
// }
}
}
判断文件是否相同的MD5:
package com.alex.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.digest.DigestUtils;
/**
* MD5工具类,返回文件的MD5值
* @author 巧云
*
*/
public class MD5Util {
private MD5Util(){}
private static char[] hexChar={'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f'};
public static String getHash(String filepath) throws NoSuchAlgorithmException, IOException{
String hashType="MD5";
File f=new File(filepath);
if(f.exists()){
InputStream is=new FileInputStream(f);
byte[] buffer=new byte[8192];
MessageDigest md5=MessageDigest.getInstance(hashType);
int len;
while((len=is.read(buffer))!=-1){
md5.update(buffer, 0, len);
}
is.close();
return DigestUtils.md5Hex(md5.digest());
}else{
return "";
}
}
public static void main(String[] args) throws Exception, IOException{
System.out.println("开始计算md5值");
String filepath="D:\\workplace\\DMSystem02\\client\\wtmpx";
//String hashType="MD5";
String hash=getHash(filepath);
System.out.println("MD5:"+hash);
}
}
还有匹配文档的MatchString类:
package com.alex.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.alex.Clientlog;
/**
* 读取log.txt文件,使用正则表达式取得需要值,保存到数组
* @author Administrator
*
*/
public class MatchString {
public static void main(String[] args) throws IOException{
InputStreamReader isr=new InputStreamReader(new FileInputStream("."+File.separator+"client"+File.separator+"log.txt"));
BufferedReader br=new BufferedReader(isr);
//声明一个login-out.txt文件,保存配对信息
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("."+File.separator+"client"+File.separator+"login_out.txt"));
PrintWriter pw=new PrintWriter(osw);
//声明一个login.txt文件,保存配对信息
OutputStreamWriter oswin=new OutputStreamWriter(new FileOutputStream("."+File.separator+"client"+File.separator+"login.txt"));
PrintWriter pwin=new PrintWriter(oswin);
String line=null;
//新建两个集合,loginmap和loginoutmap集合,使用username+pid做key,所有类容做value
Map<String,Clientlog> loginMap=new HashMap<String, Clientlog>();
Map<String,Clientlog> logoutMap=new HashMap<String, Clientlog>();
while((line=br.readLine())!=null){
System.out.println(line);
Pattern p=Pattern.compile("\\w+=([\\w.]+)");
Matcher m=p.matcher(line);
ArrayList<String> strs=new ArrayList<String>();
while(m.find()){
strs.add(m.group(1));
}
Clientlog clientLog=new Clientlog();
clientLog.setUsername(strs.get(0));
System.out.println("clientname:"+clientLog.getUsername());
clientLog.setPid(Integer.parseInt(strs.get(1)));
System.out.println("clientpid:"+clientLog.getPid());
clientLog.setType(Short.parseShort(strs.get(2)));
System.out.println("clienttype:"+clientLog.getType());
clientLog.setTime(Integer.parseInt(strs.get(3)));
System.out.println("clienttime:"+clientLog.getTime());
clientLog.setIp(strs.get(5));
System.out.println("clientip:"+clientLog.getIp());
System.out.println("------------");
//从loginoutmapvalue中得到value查找loginmap,如果有,从入新表match.txt,剩余存于login.txt
//发送match到服务器
if(clientLog.getType()==8){
logoutMap.put(clientLog.getUsername()+clientLog.getPid(), clientLog);
System.out.println("logout:"+logoutMap.get(clientLog.getUsername()+clientLog.getPid()));
}else{
loginMap.put(clientLog.getUsername()+clientLog.getPid(), clientLog);
System.out.println("login:"+loginMap.get(clientLog.getUsername()+clientLog.getPid()));
}
}
//关闭流
br.close();
//遍历Map从logoutMap中得到每一个key,查找loginMap是否存在value与之对应
Set<Entry<String,Clientlog>> entry=logoutMap.entrySet();
for(Entry<String,Clientlog> s:entry){
System.out.println("logoutMap:key:"+s.getKey()+"value:"+s.getValue());
}
//查看loginMap对象
Set<Entry<String,Clientlog>> entryin=loginMap.entrySet();
for(Entry<String,Clientlog> r:entryin){
System.out.println("loginMap:key:"+r.getKey()+"value:"+r.getValue());
}
//创建一个新的list来保存login_out对象
ArrayList<Clientlog> log=new ArrayList<Clientlog>();
//创建一个list保存未配对的login对象
ArrayList<Clientlog> loginClient=new ArrayList<Clientlog>();
System.out.println("----------------------");
for(Entry<String,Clientlog> e:entry){
String clientKey=e.getKey();
if(loginMap.containsKey(clientKey)){
Clientlog loginlog=loginMap.remove(clientKey);
System.out.println(loginlog);
Clientlog login_out=new Clientlog();
login_out.setUsername(e.getValue().getUsername());
login_out.setPid(e.getValue().getPid());
login_out.setType(e.getValue().getType());
login_out.setTime(loginlog.getTime());
login_out.setLogoutTime(e.getValue().getTime());
login_out.setIp(e.getValue().getIp());
log.add(login_out);
}
}
for(int i=0;i<log.size();i++){
System.out.println(log.get(i));
//保存配对信息到login-out.txt
pw.println(log.get(i));
}
pw.flush();
pw.close();
//保存未配对的login对象
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
for(String t:loginMap.keySet()){
System.out.println(loginMap.get(t));
pwin.println(loginMap.get(t));
}
pwin.flush();
pwin.close();
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
// //删除log.txt文件
// File file=new File("."+File.separator+"client"+File.separator+"log.txt");
// if(file.delete()){
// System.out.println("删除文件成功");
// }else{
// System.out.println("删除文件失败");
// }
}
}