Java Socket simply realizes communication between client and server (imitating chat room)

Java Socket TCP protocol simply realizes the communication between client and server

Execution effect:

  1. Start the server and 3 clients
    Service-Terminal
    Insert picture description here
  2. Group chat and private chat
    Client 1

Client 2

Implementation process:

  • Server :
    First create a server socket ServerSocket object and bind the port (start the server), then ServerSocket calls the accept method to block waiting to receive a client's request, and every time a request is received, it returns a Socket object of the client (with Socket The object can obtain the input and output streams of the client and then perform message transmission), and start a new thread to process the messages of the client, such as client online messages, client offline messages, group messages, private chat messages and then perform corresponding processing .

note: The Socket object obtains the input and output streams of the client is also blocking, for example, the readline method reads "\n" before the end of the reading will be considered, otherwise the program has been blocked there, but the read method does not know when the reading ends because It does not know when the sender finishes sending the message, unless the sender closes the output stream, and then reads to -1, it will finish reading, but after the sender closes the output stream, it can no longer send messages to the receiver. There is no Involved, but when the receiver ends reading the message is a question worth considering.

  • Client :
    First create a client socket Socket object based on the server address and port. With the Socket object above, you can get the input and output streams to the server and read and write messages, and then create a thread to monitor and process the server's messages. Get the user input and send it to the server (input exit message here means exit the server, input @xxx:message format message means private chat to send message to xxx client, other messages are unified as group chat messages, and the server will directly forward them to others after receiving All clients)

Server code

public class Server {
    
    
    private int port = 5210;
    private ServerSocket server_socket;
    private Map<String,Socket> clients;   //存放所有访问服务器的客户端和其用户名

    public Server() throws Exception {
    
    
        //1-初始化
        server_socket = new ServerSocket(this.port);   //创建服务器
        clients = new HashMap<>();

        //2-每次接收一个客户端请求连接时都启用一个线程处理
        while(true) {
    
    
            //accept方法一直阻塞直到接收到一个客户端的请求 并返回该客户端的套接字socket
            Socket client_socket = server_socket.accept();
    		//开启新线程处理客户端的请求
            new HandleClientThread(client_socket).start();
        }
    }

    /** ----------------------------------------------------------------------------------------------------
     *      启用一个线程处理一个客户端的请求
     */
    private class HandleClientThread extends Thread{
    
    
        private Socket client_socket;    //
        private BufferedReader server_in;
        private PrintWriter server_out;
        private String client_Name;

        public HandleClientThread(Socket client_socket) {
    
    
            try {
    
    
                //初始化
                this.client_socket = client_socket;
                server_in = new BufferedReader(new InputStreamReader(this.client_socket.getInputStream()));
                server_out = new PrintWriter(this.client_socket.getOutputStream(),true);
                
                //通知刚连上的客户端输入用户名
                server_out.println("您已成功连接上聊天服务器!请输入你的用户名");

            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }


        //处理客户端消息
        public void run(){
    
    
            try {
    
    
                int falg = 0;     //判断该客户端是否第一次访问
                String fromClientData;

                //循环接收该客户端发送的数据
                while((fromClientData = server_in.readLine()) != null){
    
    
                    //该客户端请求关闭服务器的连接
                    if("exit".equals(fromClientData)){
    
    
                        Server.this.offline(this.client_Name);
                        break;
                    }

                    //判断该客户端是否第一次访问
                    if(falg++ == 0){
    
    
                        this.client_Name = fromClientData;
                        clients.put(this.client_Name,this.client_socket);  
                        sendtoAllClient("欢迎:"+this.client_Name+"进入聊天室");
                        Server.this.showUserList();
                        continue;
                    }

                    //处理私聊    格式  @接收客户端的名字:对其说的话
                    if(fromClientData.startsWith("@")){
    
    
                        String receiveName = fromClientData.substring(1,fromClientData.indexOf(":"));
                        String message = fromClientData.substring(fromClientData.indexOf(":")+1,fromClientData.length());

                        sendtoUser(this.client_Name,receiveName,message);

                    }else {
    
    
                        //处理群发群发
                        sendtoAllClient(this.client_Name+"说:"+fromClientData);
                    }

                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
    }

    //显示所有用户列表
    private synchronized  void showUserList(){
    
    
        System.out.println("\n*****用户列表****");
        System.out.println("在线人数:"+clients.size());
        for (Map.Entry<String,Socket> user:clients.entrySet()){
    
    
            System.out.println("---"+user.getKey());
        }
    }

    //广播消息message给所有客户端
    private synchronized  void sendtoAllClient(String message){
    
    
        try {
    
    
            //获取所有客户端套接字socket的输出流
            for (Map.Entry<String,Socket> user:clients.entrySet()) {
    
    
               PrintWriter server_out = new PrintWriter(user.getValue().getOutputStream(),true);
                server_out.println(message);
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    //转发消息给某个特定的客户端  
    private synchronized void sendtoUser(String senduser,String receiveuser,String message){
    
    
        try {
    
    
            PrintWriter out = new PrintWriter( clients.get(receiveuser).getOutputStream(),true);
            out.println(senduser+"对你说:"+message);

        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }


    //某个客户端退出服务器
    private synchronized void offline(String username){
    
    
            clients.remove(username);
            if(username !=  null)
            sendtoAllClient(username+"已下线!");
            Server.this.showUserList();
    }

    public static void main(String[] args) throws Exception {
    
    
        new Server();

    }
}

Client

public class Client {
    
    
    private String ip_adress = "127.0.0.1";
    private final int port = 5210;

    private PrintWriter client_out;   //发送消息给服务器的输出流
    private BufferedReader client_in;  //接收服务器消息的输入流
    private Socket client_socket;   //客户端套接字

    public  Client() throws IOException {
    
    
        //1-初始化
        client_socket = new Socket(ip_adress,port); //根据ip,端口连接服务器
        client_in = new BufferedReader(new InputStreamReader(client_socket.getInputStream()));
        client_out = new PrintWriter(client_socket.getOutputStream(),true);
        
        //2-开启新线程处理监听服务器端发来的消息
        new ClientThread().start();

        //3-客户端循环发送群聊,私聊消息
        while(true){
    
    
            //获取客户端的输入
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String input = br.readLine();
            client_out.println(input);  //发送消息给服务器

            //4-客户端退出服务器
            if(input.equals("exit")){
    
    
                client_out.close();
                client_in.close();
                client_socket.close();
                System.exit(0);
            }
        }
    }

   //-----------------------------------------------------------------
    /**
     *          监听服务器端发来的消息
     */
    private class ClientThread extends Thread{
    
    
        public void run(){
    
    
            try {
    
    
            		//接收服务器消息
                    String fromServer_data;
                    while((fromServer_data=client_in.readLine()) != null){
    
    
                         System.out.println(fromServer_data);
                    }
            } catch (IOException e) {
    
    
            }
        }
    }

    
	 //启动客户端
    public static void main(String[] args) throws IOException {
    
    
            new Client();  
    }
}

Reward

If you find the article useful, you can encourage the author

Insert picture description here


Guess you like

Origin blog.csdn.net/weixin_41347419/article/details/88630037