用Java控制台实现简单的群聊天室

需求分析:
实现简单的群聊,需要用到Java的Socket(套接字)和ServerSocket(服务器端套接字)两个类。当客户端(Socket)发送信息到固定的服务器(ServerSocket)的地址和端口,会有服务器端监听到该信息,然后转发至每个用户,即聊天室。要想把信息转发到各个用户,需要把这所有的用户用一个集合(List)存起来,遍历集合内所有用户,进行发送。
其中难点在于如何使用多线程接受转发信息。对于服务器端,需要不断监听用户端的信息传输,每当监听到一个用户发来消息,会开辟一个线程对消息转发至各个用户。对于客户端,每创建一个用户,需要开辟一条线程,并且该用户需要接收和发送消息,接收和发送消息两者间是不同步的,又需要开辟两条线程,线程下面有线程。
代码如下:
1、服务器端

/**
    服务器端,服务器创建入口
*/
public Server{
    public static void  main(String[] args){
        //创建一个服务器,端口号为8000
        ServerSocket server = new ServerSocket(8000);
            //创建一个死循环,让服务器一直处于监听客户端信息的状态
            while(true){
                Socket socket = server.accept();
                //传入监听到的socket,并且启动线程
                ServerThread st = new SeverThread(socket);
                Thread th = new Thread(st);
                th.start();
                //异常未处理
            }
      }  
}

2、当监听到来自客户端的消息,开辟新的服务器用来接收

/**
    服务器子线程端
*/
public ServerThread implements Runnable {
    private static LinkedList list = new LinkedList<>();
    private Socket socket;
    public ServerSocket(Socket socket){
        //把监听到的socket传过来
        this.socket = socket;
        //并且添加到集合中
        list.add(socket);
    }
    @Override
    public void run(){
        //接收客户端发过来的消息(读)
        //为了提高读写效率,把字节流用转换流转换为字符流
        //然后用缓存流封装转换流
        BufferedReader br = null;
        try{
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String msg = null;
            while((msg = br.readLine()) != null){
                sendAll(msg);
            }
        } catch(IOException e){
            e.printStackTrace();
        }
    }

    //发送给所有人
    public void sendAll(String msg){
        //遍历集合,然后发送给集合(群)里面的所有人
        PrintStream ps = null;
        for(Socket sk : list){
            try{
                ps = new PrintStream(sk.getOutputStream());
                ps.println(msg);
                ps,flush();
            } catch(IOException e){
                e.printStackTrace();
            }
        }
    }    

}

3、客户端,每个用户的入口,每当有用户进入,会开辟一条线程

public Client{
    public static void main(String[] srgs){
         ClientThread ct = new ClientThread();
         Thread th = new Thread(ct);
         th.start();
    }
}

4、客户端子线程,每当接收和发送消息,会开辟线程用来同步

public ClientThread implements Runnable{
    @Override
    public run(){
        Socket socket = null;
        try {
            //使用当前主机服务器,端口号设为8000
            socket = new Socket("localhost", 8000);
            Thread th_1 = new Thread(new ClientReceive(socket));
            th_1.start();

            Thread th_2 = new Thread(new ClientSend(socket));
            th_2.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }
}

5、客户端发送信息子线程

public ClientSend implements Runnable{

    private Socket socket;
    
    public ClientSend(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run(){
         //发送信息
        PrintStream ps = null;
        Scanner input = new Scanner(System.in);
        try {
           while(ture) {
                //输入发送的信息(写)
                ps = new PrintStream(socket.getOutputStream());
                String msg = input.next();
                ps.println(msg);
                ps.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

6、客户端接受信息子线程

public ClientReceive implements Runnable{

    private Socket socket;
    
    public ClientReceive(Socket socket){
        this.socket = socket;
    }
    
    @Override
    public void run(){
        BufferedReader br = null;
        String msg = null;
        //接收信息(读)
        try {
           while(true) {
                    br = new BufferedReader(new InputStreamReader(socket.getInputStream));
                 while((msg = br.readLine()) != null) {
                    System.out.println(msg);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

你可能感兴趣的:(用Java控制台实现简单的群聊天室)