当前位置:网站首页>BIO模型实现多人聊天

BIO模型实现多人聊天

2022-07-06 06:47:00 qq_44116526

1、服务端

package com.li.server;

import jdk.net.Sockets;

import javax.sound.sampled.Port;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * @author liyakun
 */
public class ChatServer {
    
    private int DEFAULT_PORT = 8886;
    private final String QUIT = "quit";
    private ServerSocket serverSocket;
    private Map<Integer, Writer> connectedClients;

    public ChatServer() {
    
        connectedClients = new HashMap<Integer, Writer>();
    }

    public synchronized void addClient(Socket socket) throws IOException {
    
        if (socket != null) {
    
            int port = socket.getPort();
            BufferedWriter bufferedWriter = new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream())
            );
            connectedClients.put(port, bufferedWriter);
            System.out.println("端口号:" + port + "已连接服务器");
        }
    }

    public synchronized void removeServer(Socket socket) throws IOException {
    
        if (socket != null) {
    
            int port = socket.getPort();
            if (connectedClients.containsKey(port)) {
    
                connectedClients.get(port).close();
            }
            connectedClients.remove(port);
            System.out.println("客户端" + port + "已下线");
        }
    }

    public synchronized void forwardMessage(Socket socket, String fwdMsg) throws IOException {
    
        for (Integer integer : connectedClients.keySet()) {
    
            if (!integer.equals(socket.getPort())) {
    
                Writer writer = connectedClients.get(integer);
                writer.write(fwdMsg);
                writer.flush();
            }
        }
    }

    /**
     * 检查用户是否退出
     * @param msg
     * @return
     */
    public boolean readyToQuit(String msg) {
    
        return QUIT.equals(msg);
    }

    public void close() {
    
        if (serverSocket != null) {
    
            try {
    
                serverSocket.close();
                System.out.println("关闭serverSocket");
            } catch (IOException e) {
    
                e.printStackTrace();
            }
        }
    }

    public void start() {
    
        try {
    
            serverSocket = new ServerSocket(DEFAULT_PORT);
            System.out.println("服务器启动,监听端口" + DEFAULT_PORT);
            while (true) {
    
                //等待客户端连接
                Socket socket = serverSocket.accept();
                //创建chatHandler线程
                new Thread(new ChatHandler(this,socket)).start();
            }
        } catch (IOException e) {
    
            e.printStackTrace();
        } finally {
    
            close();
        }
    }

    public static void main(String[] args) {
    
        ChatServer chatServer = new ChatServer();
        chatServer.start();
    }
}

package com.li.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * @author liyakun
 */
public class ChatHandler implements Runnable {
    
    private ChatServer chatServer;
    private Socket socket;

    public ChatHandler(ChatServer chatServer, Socket socket) {
    
        this.chatServer = chatServer;
        this.socket = socket;
    }

    @Override
    public void run() {
    
        try {
    
            //存储新上线用户
            chatServer.addClient(socket);
            //读取用户发送的信息
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String msg=null;
            while ((msg=bufferedReader.readLine())!=null){
    
                String fwdMsg="客户端【"+socket.getPort()+"]"+msg+"\n";
                System.out.println(fwdMsg);
                chatServer.forwardMessage(socket,fwdMsg);
                //检查用户是否退出
                if(chatServer.readyToQuit(msg)){
    
                    break;
                }
            }
        } catch (IOException e) {
    
            e.printStackTrace();
        }finally {
    
            try {
    
                chatServer.removeServer(socket);
            } catch (IOException e) {
    
                e.printStackTrace();
            }
        }
    }
}

2、客户端

package com.li.client;

import java.io.*;
import java.net.Socket;

/**
 * @author liyakun
 */
public class ChatClient {
    
    private final String DEFAULT_SERVER_HOST = "127.0.0.1";
    private final int DEFAULT_SERVER_PORT = 8886;
    private final String QUIT = "quit";
    private Socket socket;
    private BufferedReader reader;
    private BufferedWriter writer;

    //发送信息给服务器
    public void send(String msg) throws IOException {
    
        if (!socket.isOutputShutdown()) {
    
            writer.write(msg + "\n");
            writer.flush();
        }
    }

    public String receive() throws IOException {
    
        String msg = null;
        if (!socket.isInputShutdown()) {
    
            msg = reader.readLine();
        }
        return msg;
    }

    //检查用户是否准备退出
    public boolean readyToQuit(String msg) {
    
        return QUIT.equals(msg);
    }

    public void close() {
    
        if (writer != null) {
    
            try {
    
                System.out.println("关闭socket");
                writer.close();
            } catch (IOException e) {
    
                e.printStackTrace();
            }
        }
    }

    public void start() {
    

        try {
    
            //创建socket
            socket = new Socket(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT);

            //创建IO流
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //处理用户输入
            new Thread(new UserInputHandler(this)).start();
            //读取服务器转发的信息
            String msg = null;
            while ((msg = receive()) != null) {
    
                System.out.println(msg);
            }
        } catch (IOException e) {
    
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
    
        ChatClient chatClient = new ChatClient();
        chatClient.start();
    }
}

package com.li.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author liyakun
 */
public class UserInputHandler implements Runnable {
    
    private ChatClient chatClient;

    public UserInputHandler(ChatClient chatClient) {
    
        this.chatClient = chatClient;
    }

    @Override
    public void run() {
    
        try {
     //等待用户输入信息
            BufferedReader consoleReader =
                    new BufferedReader(new InputStreamReader(System.in));
            while (true) {
    

                String input = consoleReader.readLine();
                //向服务器发送信息
                chatClient.send(input);
                //检查用户是否准备退出
                if (chatClient.readyToQuit(input)) {
    
                    break;
                }
            }
        } catch (IOException e) {
    
            e.printStackTrace();
        }
    }
}

3、测试:
在IDEA中运行服务端,并开启多个客户端(开启方法editConfigurations------>Allow parallel run),便可以测试成功。

原网站

版权声明
本文为[qq_44116526]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_44116526/article/details/125628612