java socket 实现多个客户端通过服务器一对一聊天并实现文件传输
服务器端:
package cn.com.test09; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Set; public class t12 { public static void main(String[] args) { // TODO Auto-generated method stub new ServerOb(8080); } } class ServerOb{ private int port; ServerSocket ss; public ServerOb(int p){ this.port=p; try { ss = new ServerSocket(port); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } while(true){ try { Socket soc = ss.accept(); new Thread(new clientO(soc)).start(); } catch (IOException e) { // TODO Auto-generated catch block System.out.println(" ServerOb 构造函数 出错"); e.printStackTrace(); } } } } class clientO implements Runnable{ public static HashMap<String, Socket> map= new HashMap<String, Socket>(); private String number = null; private Socket soc; private DataInputStream in; private DataOutputStream out; public clientO(Socket s){ this.soc=s; try { this.in=new DataInputStream(soc.getInputStream()); this.out=new DataOutputStream(soc.getOutputStream()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } getKey(); } public String getNumber(){ try { number=in.readUTF();//1 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return number; } public void getKey(){ map.put(getNumber(), soc);//得到帐号保存Map Set<String> ke = map.keySet(); if(ke!=null) try { out.writeUTF(ke.toString());//2 out.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void run() { // TODO Auto-generated method stub String oth; try { while(true){ oth = in.readUTF(); if(oth.equalsIgnoreCase("l")){ getOtherNumber(); } if(oth.equalsIgnoreCase("w")){ getFileransmission(); } if(oth.equalsIgnoreCase("t")){ in.close(); out.close(); map.remove(number); soc.close(); break; } }} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println("run 中出错"); } } public void getFileransmission(){ while(true){ try { String oth = in.readUTF();//传输对象编号 if(oth.equalsIgnoreCase("bye")){ return; } Socket other = map.get(oth);//取得传输对象socket String fileName = in.readUTF();//传输文件名 DataOutputStream asd = new DataOutputStream(other.getOutputStream()); asd.writeUTF("w"); asd.flush(); asd.writeUTF(number+"====="+fileName); asd.flush(); // 文件字节传输 byte[] b= new byte[1024]; int i=0; while((i=in.read(b))!=-1){ asd.write(b, 0, i); asd.flush(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println(number+"文件传输出错"); } } } public void getOtherNumber(){ while(true){ try { System.out.println("hhhhhhhhhhhhhhhhhh"); String oth = in.readUTF();//4 System.out.println(oth); Socket other = map.get(oth); DataOutputStream asd = new DataOutputStream(other.getOutputStream()); if(oth.equalsIgnoreCase("bye")){ return; } String value = in.readUTF();//5 String str=number +"对你说:\r\n"+value; asd.writeUTF("l"); asd.flush(); asd.writeUTF(str); asd.flush(); if(value.equalsIgnoreCase("bye")){ return; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println(number+"聊天传输出错"); } } } }
客户端:
package cn.com.test09; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; import java.util.Scanner; public class t13 { public static void main(String[] args) { new ClientOO("192.168.0.105",8080,"a");//服务器ip 服务器端口 自身编号 } } class ClientOO{ private String path; private int port; private String name; private Scanner sca= new Scanner(System.in); private DataInputStream in; private DataOutputStream out; public ClientOO(String path,int port,String name){ this.path=path; this.port=port; this.name=name; try { Socket s=new Socket(path,port); this.in=new DataInputStream(s.getInputStream()); this.out=new DataOutputStream(s.getOutputStream()); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } send(); hhhhh(); } public void send(){ String s = null; try { out.writeUTF(name);// 1 out.flush(); s=in.readUTF();//2 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("在线列表:"+s); } public void hhhhh(){ while(true){ System.out.println("聊天请输入 l 文件传输请输入 w 退出 请输入 t "); String str=sca.next(); if(str.equalsIgnoreCase("l")){ try { out.writeUTF(str); out.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("===================="); MyServerReader1 hhhh = new MyServerReader1(in); MyServerWriter1 wwwwww = new MyServerWriter1(out,str); hhhh.start(); wwwwww.start(); try { wwwwww.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(str.equalsIgnoreCase("w")){ try { out.writeUTF(str); out.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } MyServerReader1 hhhh = new MyServerReader1(in); MyServerWriter1 wwwwww = new MyServerWriter1(out,str); hhhh.start(); wwwwww.start(); try { wwwwww.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(str.equalsIgnoreCase("t")){ try { out.writeUTF(str); out.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("你退出系统"); System.exit(0); } } } } class MyServerReader1 extends Thread { private DataInputStream dis; private String str; public MyServerReader1(DataInputStream dis) { this.dis = dis; } public void run() { try { str=dis.readUTF(); if(str.equalsIgnoreCase("l")){ liaotian(); } if(str.equalsIgnoreCase("w")){ wenjian(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void wenjian (){ String fileName; try { String[] hhh = dis.readUTF().split("====="); fileName =hhh[1] ; File f= new File("F:\\"+fileName); OutputStream os= new FileOutputStream(f); byte[] b= new byte[1024]; int i=0; while((i=dis.read(b))!=-1){ os.write(b, 0, i); } os.close(); System.out.println(hhh[0]+"给你传输了文件:"+fileName); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void liaotian(){ String info; try { while (true) { // 如果对方,即客户端没有说话,那么就会阻塞到这里, // 这里的阻塞并不会影响到其他线程 info = dis.readUTF(); // 如果状态有阻塞变为非阻塞,那么就打印接受到的信息 System.out.println("对方说: " + info); if (info.equals("bye")) { System.out.println("对方下线,选着其他好友!"); break; } } } catch (IOException e) { e.printStackTrace(); } } } // 从键盘获得输入流并写入信息到客户端 class MyServerWriter1 extends Thread { private DataOutputStream dos; private Scanner sc; private String str; public MyServerWriter1(DataOutputStream dos,String s) { this.dos = dos; this.str=s; this.sc=new Scanner(System.in); } public void run() { if(str.equalsIgnoreCase("l")){ liaotian(); }if(str.equalsIgnoreCase("w")){ wenjian(); } } public void wenjian(){ System.out.println("=======进入文件传输======="); String s= sc.next(); try { dos.writeUTF(s); dos.flush(); System.out.println("输入本地文件路径:"); String filepath= sc.next(); String filename=filepath.substring(filepath.lastIndexOf("\\")+1); dos.writeUTF(filename); dos.flush(); File f= new File(filepath); InputStream in= new FileInputStream(f); byte[] b= new byte[1024]; int i=0; while((i=in.read(b))!=-1){ dos.write(b, 0, i); } dos.flush(); in.close(); System.out.println("对"+s+"文件传输完成"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void liaotian (){ System.out.println("=======进入聊天======="); String info; try { while (true) { info = sc.next();//4 if (info.equals("bye")) { System.out.println("结束与对方聊天!"); break; } dos.writeUTF(info); dos.flush(); info = sc.next();///5 dos.writeUTF(info); dos.flush(); if (info.equals("bye")) { System.out.println("结束与对方聊天!"); break; } } } catch (IOException e) { e.printStackTrace(); } } }