如何实现基于Socket的群聊和广播通信?代码举例讲解

实现基于Socket的群聊和广播通信可以采用以下思路:
1、 服务端:

  • 创建ServerSocket,监听客户端连接。
  • 为每个客户端连接创建一个线程,负责数据传输。
  • 将接收到的消息广播给所有客户端连接。

2、 客户端:

  • 连接服务端,获取输入流和输出流。
  • 发送消息给服务端。
  • 接收服务端广播的消息。

3、 数据格式:

  • 消息前添加消息长度字段,便于接收方解析完整的消息。
  • 消息前添加用户信息(用户名、IP等),以区分不同用户发送的消息。

示例代码:

服务端:

public class ChatServer {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8000);
        List<Socket> sockets = new ArrayList<>();

        while (true) {
            Socket socket = server.accept();
            sockets.add(socket);
            new Thread(new ClientHandler(socket, sockets)).start();
        }
    }
}

class ClientHandler implements Runnable {
    private Socket socket;
    private List<Socket> sockets;

    public ClientHandler(Socket socket, List<Socket> sockets) {
        this.socket = socket;
        this.sockets = sockets;
    }

    @Override
    public void run() {
        try {
            InputStream in = socket.getInputStream();
            OutputStream out = socket.getOutputStream();

            while (true) {
                // 读取消息
                byte[] lengthBytes = new byte[4];
                in.read(lengthBytes);
                int length = ByteToInt(lengthBytes);
                byte[] data = new byte[length];
                in.read(data); 

                // 广播消息
                for (Socket clientSocket : sockets) {
                    OutputStream clientOut = clientSocket.getOutputStream();  
                    clientOut.write(data);
                }
            }
        } catch (IOException e) {
            sockets.remove(socket);
        }
    }
}

客户端:

public class ChatClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 8000);
        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();

        new Thread(new ReceiveMessageHandler(in)).start();

        Scanner scanner = new Scanner(System.in);
        while (true) {
            String msg = scanner.nextLine();
            byte[] data = msg.getBytes();
            byte[] lengthBytes = IntToByte(data.length); 

            // 构建消息
            byte[] packet = join(lengthBytes, data); 

            // 发送消息
            out.write(packet); 
        }
    }
}

class ReceiveMessageHandler implements Runnable {
    private InputStream in;

    public ReceiveMessageHandler(InputStream in) {
        this.in = in; 
    }

    @Override
    public void run() {
        try {
            while (true) {
                // 接收广播消息
                byte[] lengthBytes = new byte[4];
                in.read(lengthBytes);
                int length = ByteToInt(lengthBytes);
                byte[] data = new byte[length];
                in.read(data);

                String msg = new String(data);
                System.out.println(msg);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}