学了一个月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("删除文件失败"); // } } }