• 多线程+socket实现多人聊天室


    最近在学习多线程的时候打算做一个简单的多线程socke聊天的程序,结果发现网上的代码都没有完整的实现功能,所以自己实现了一个demo:

    demo功能大致就是,有一个服务端负责信息转发,多个客户端发送消息,当一个客户端发送消息时,其他的客户端都可以接受到。

    服务端:

    客户端:

    客户端代码:

    package com.cky.client;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.Scanner;
    
    public class Client {
        private PrintWriter out;
        //private BufferedReader br;
        private Scanner scan;
        private Boolean flag=true;
        private Socket s;
        private InputStream is;
        
        public Client() throws UnknownHostException, IOException {
            s=new Socket("127.0.0.1", 5001);
            is=s.getInputStream();
        }
        
        public static void main(String []args) throws UnknownHostException, IOException {
            Client client =new Client();
            client.startup();
        }
        public void startup() throws UnknownHostException, IOException {
            out = new PrintWriter(s.getOutputStream(), true);  
            
            //开启一个线程监听服务端的消息
            Thread ct=new Thread(new Runnable() {
                @Override
                public void run() {
                    while(true) {
                        if(!flag) break;
                        try {
                            receive();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            });
            ct.start();
            //主线程负责发送消息
            System.out.println("请输入你的用户名:");
            scan = new Scanner(System.in);
            String name=scan.nextLine();
            out.println(name);
            System.out.println(name+",欢迎进入聊天室,输入quit退出");
            while(flag) {
                String read=scan.nextLine();
                if(read.equalsIgnoreCase("quit")) {
                    flag=false;
                }
                //System.out.println(read);
                out.println(read);
            }
            s.close();
        }
        
        public void receive() throws IOException {
            byte ss[]=new byte[1024];
            int length=s.getInputStream().read(ss);
            System.out.println(new String(ss,0,length));
        }
    }

    服务端代码:

    package com.cky.server;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.List;
    
    public class Server {
        private List<ThreadServer> clients=new ArrayList<ThreadServer>();
        public void startup() throws IOException {
            System.out.println("监听5001端口");
            ServerSocket ss=new ServerSocket(5001);
            while(true){
                Socket socket=ss.accept();
                System.out.println("发现新用户");
                Thread st=new Thread(new ThreadServer(socket));
                st.start();
            }
        }
        
        public class ThreadServer implements Runnable{
            private Socket socket;
            private BufferedReader br;
            private PrintWriter out;
            private String name;
            private Boolean flag=true;
            public ThreadServer(Socket socket) throws IOException {
                this.socket=socket;
                br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out=new PrintWriter(socket.getOutputStream(),true);
                String str=br.readLine();
                name=str+"["+socket.getInetAddress().getHostAddress()+":"+socket.getPort()+"]";
                System.out.println(name+"加入该聊天室");
                send(name+"加入该聊天室");
                clients.add(this);
            }
            private void send(String message) {
                for (ThreadServer threadServer : clients) {
                    System.out.println("-->已向线程"+threadServer.name+"发送消息");
                    threadServer.out.print(message);
                    threadServer.out.flush();
                }
            }
            private void receive() throws IOException {
                String message;
                while(flag=true) {
                    message=br.readLine();
                    if(message.equalsIgnoreCase("quit")) {
                        System.out.println("用户"+name+"退出了");
                        out.println("quit");
                        out.flush();
                        clients.remove(this);
                        flag=false;
                    }
                    System.out.println(name+":"+message);
                    send(name+":"+message);
                }
            }
            @Override
            public void run() {
                try {
                    while(flag=true) {
                        receive();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        
        public static void main(String []args) throws IOException {
            Server server=new Server();
            System.out.println("服务器开启");
            server.startup();
        }
        
    }

    先启动服务端,监听端口,再使用客户端登录发送消息。

  • 相关阅读:
    sql 有条件计数
    easyui combox 手动添加项
    只有设置了 name 属性的表单元素才能在提交表单时传递它们的值
    除湿方法
    android 页面跳转,数据回传
    android studio 乱码
    android studio 工具
    gridlaylout 简单布局
    android 开发 简单的页面布局
    android sdk
  • 原文地址:https://www.cnblogs.com/chenkeyu/p/7850727.html
Copyright © 2020-2023  润新知