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 +"对你说:
"+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();
        }
    }
}
原文地址:https://www.cnblogs.com/anholt/p/3663519.html