处理粘包和拆包问题的方法
- 定长数据包:发送端发送固定长度的数据包,接收端每次按固定长度读取数据。这种方式简单,但可能造成空间浪费。
- 包尾添加特殊分隔符:在每个数据包的末尾添加特殊的分隔符,接收端根据分隔符来识别数据包的结束。
- 包头加上包体长度:在包头中定义一个字段来表示包体的长度,接收端先读取包头获取包体长度,再根据长度读取包体内容。
使用“包头加上包体长度”方法的代码示例
发送端代码
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class SocketSender {
public static void main(String[] args) {
try (Socket socket = new Socket("127.0.0.1", 8888);
DataOutputStream dos = new DataOutputStream(socket.getOutputStream())) {
String message = "Hello, Server!";
// 发送包体长度
dos.writeInt(message.length());
// 发送包体
dos.writeUTF(message);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
接收端代码
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketReceiver {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
DataInputStream dis = new DataInputStream(socket.getInputStream())) {
// 读取包体长度
int length = dis.readInt();
// 读取包体
String message = dis.readUTF();
System.out.println("Received message: " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
}