TCP协议是面向连接的,提供可靠的字节流服务。在TCP传输中,可能会出现粘包和拆包的情况:
粘包:发送方发送的多个数据包在接收方 Reform成一个数据包。
拆包:发送方发送的一个数据包在接收方被拆成多个数据包。
实现TCP粘包和拆包处理主要有以下两种方式:
- 根据数据包长度字段:在每个数据包头部添加数据包长度字段,接收方根据此长度字段读取完整的数据包。
示例:
发送方:
byte[] data = "Hello, world!".getBytes();
byte[] lengthBytes = IntToByte(data.length);
byte[] packet = join(lengthBytes, data);
socket.write(packet);
接收方:
byte[] lengthBytes = new byte[4];
socket.read(lengthBytes);
int length = ByteToInt(lengthBytes);
byte[] data = new byte[length];
socket.read(data);
- 根据特定的分隔符:发送方根据事先约定的分隔符(如\n)拆分数据包,接收方根据此分隔符重组完整的数据包。
示例:
发送方:
String data = "Hello\nworld!\n";
socket.write(data.getBytes());
接收方:
byte[] buffer = new byte[1024];
int offset = 0;
while (true) {
int length = socket.read(buffer, offset, buffer.length - offset);
if (length == -1) break;
offset += length;
int pos;
while ((pos = find(buffer, 0, offset, '\n')) != -1) {
byte[] pkg = Arrays.copyOf(buffer, pos);
// 处理数据包
offset -= pos + 1;
System.arraycopy(buffer, pos + 1, buffer, 0, offset);
}
}