实现基于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();
}
}
}