如何实现TCP协议下的粘包和拆包处理?代码举例讲解

TCP协议是面向连接的,提供可靠的字节流服务。在TCP传输中,可能会出现粘包和拆包的情况:
粘包:发送方发送的多个数据包在接收方 Reform成一个数据包。
拆包:发送方发送的一个数据包在接收方被拆成多个数据包。

实现TCP粘包和拆包处理主要有以下两种方式:

  1. 根据数据包长度字段:在每个数据包头部添加数据包长度字段,接收方根据此长度字段读取完整的数据包。
    示例:
    发送方:
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);
  1. 根据特定的分隔符:发送方根据事先约定的分隔符(如\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);
    } 
}