java 网络编程-TCP-多人群聊究极版

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 网络编程-TCP-多人群聊究极版相关的知识,希望对你有一定的参考价值。

客户端:
多个客户可以正常收发信息,因为可以同时发送和接受信息,不是发送完信息后等待
返回信息,所以要加入多线程

 public class Client 

public static void main(String[]args) throws UnknownHostException, IOException

    System.out.println("客户端启动中...");
    BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
    System.out.println("请输入用户名:");
    String name=br.readLine();
    Socket client =new Socket("localhost",9999);

    new Thread(new Send(client,name)).start();//在线程还没启动之前,通过构造方法发送名称,先于信息的发送,
    //因为接收信息时,名称已经发送并被读取到变量中

    new Thread(new Receive(client)).start();


作为释放资源工具类

public class utils 

public static void close(Closeable... target )

    for(Closeable it:target)
    
            try 
                if(null!=it)
                
                it.close();
                
             catch (IOException e) 

                e.printStackTrace();
            

           

客户端的发送端封装了:
发送消息
从键盘读取消息
run()
释放资源

 public class Send implements Runnable

private BufferedReader br;
private DataOutputStream dos;
private Socket client;
private boolean flag=true;
private String name;

public Send(Socket client,String name)

    this.client=client;
    this.name=name;
    br=new BufferedReader(new InputStreamReader(System.in));
    try 
        dos=new DataOutputStream(client.getOutputStream());
        //发送名称
        send(name);
     catch (IOException e) 

        this.release();
    

public void run()

    while(flag)
    
        String msg=getstr();
        send(msg);

    

private void release()

    this.flag=false;
    utils.close(dos,client);

//从控制台获取消息
private String getstr()

    try 
        String msg=br.readLine();
        return msg;
     catch (IOException e) 

        e.printStackTrace();
    
    return null;

private void send(String msg)

    try 
        dos.writeUTF(msg);
        dos.flush();

     catch (IOException e) 
    release();
    

客户端的接收端封装了:
接收消息
run()
释放资源

 public class Receive implements Runnable 
private DataInputStream dis;
private Socket client;
private boolean flag=true;

public Receive(Socket client)

    this.client=client;
    try 
        dis=new DataInputStream(client.getInputStream());
     catch (IOException e) 
        release();
    


private String receive()

    String msg;
    try 
        msg = dis.readUTF();
        return msg;
     catch (IOException e) 
        release();
    
    return null;

public void run()

    while(flag)
    
        String msg=receive();
        System.out.println(msg);
    


private void release()

    this.flag=false;
    utils.close(dis,client);

在线聊天室
服务器:

public class Chat 
private static CopyOnWriteArrayList<channel> list=new CopyOnWriteArrayList<>();//使用并发容器,适合多线程
public static void main(String[]args) throws IOException

    System.out.println("服务器启动中...");

    ServerSocket server=new ServerSocket(9999);

    while(true)
    
        Socket client =server.accept();
        System.out.println("一个客户端建立了连接");
        channel c=new channel(client);
        list.add(c);  //容器管理所有成员
        new Thread(c).start();

    



static class channel implements Runnable
    private DataInputStream dis;
    private DataOutputStream dos;
    private BufferedReader br;
    private Socket client;
    private boolean flag;
    private String name;

    public channel(Socket client)
    
        this.client=client;
        try 
            dis=new DataInputStream(client.getInputStream());
            dos=new DataOutputStream(client.getOutputStream());
            flag=true;

            //获取名称
            this.name=receive();
            //欢迎到来
            this.send("欢迎来到聊天室");
            this.sendothers(this.name+"来到了聊天室",true);

         catch (IOException e) 
            release();          
    
    //接收消息
    private String receive() 
    
        try 
            String msg=dis.readUTF();
            return msg;
         catch (IOException e) 
            release();
        
        return null;

    
    //发送给消息
    private void send(String msg)
    
        try 
            dos.writeUTF(msg);
            dos.flush();
         catch (IOException e) 
            release();
        

    
    //群聊:获取自己的消息,发给其他人和私聊功能
    private void sendothers(String msg,boolean issys)
    
        boolean issecrete =msg.startsWith("@");
        if(issecrete)
        
            int index=msg.indexOf(":");
            String target=msg.substring(1,index);
            msg=msg.substring(index+1);

            for(channel it:list)
            
                if(it.name.equals(target)) //查找目标
                
                    it.send(this.name+"悄悄地对你说:"+msg); //私聊消息
                    break;
                
            
        else
        
            for(channel it:list)
            
                if(it==this)
                
                    continue;
                
                if(!issys)
                
                    it.send(this.name+":"+msg);
                else
                
                    it.send(msg);
                
            
        
    
    private void release()
    
        this.flag=false;
        utils.close(dis,dos,client); //写一个工具类,使用Closeable...可变参数    
        //退出时,从容器里面移掉自身
        list.remove(this);
        sendothers("离开了聊天室",false);
    
    public void run()
    
        while(flag)
        
            String msg=receive();
            sendothers(msg,false);
        
        release();

    


以上是关于java 网络编程-TCP-多人群聊究极版的主要内容,如果未能解决你的问题,请参考以下文章

java 网络编程-TCP-多人群聊(自问自答)

Java 网络编程--------------------基于TCP/IP(加入多线程)

廖雪峰Java13网络编程-1Socket编程-3TCP多线程编程

Java网络编程 - TCP通信

Java网络编程基础— 基于TCP的NIO简单聊天系统

多线程_TCP编程