多线程+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();
    }
    
}

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

 

posted @ 2017-11-17 11:27  宇的季节  阅读(11134)  评论(0编辑  收藏  举报