tcp 粘包
程序员文章站
2022-05-27 22:52:02
...
由于tcp流式传输,受限于缓冲区大小,会导致一个数据包分多个发送情况。应用程序需处理该边界。
粘包常见的处理方式有以下三种:
1. 结束符方式
std::string readLine(void) { char *pos; while (!(_buffer.size()) || !(pos = strchr(_buffer.data(), '\n'))) { if (readData(_buffer, 4096) <= 0) { pos = _buffer.data() + _buffer.size() - 1; break; } } return _buffer; }
2. 4字节头报文长度
int handleProtocol() { uint32_t dwLen = 0; /// 分两次读取 // 1. 读取报文长度 if (client->read((char*)&dwLen, sizeof(uint32_t)) != sizeof(uint32_t)) { fprintf(stderr, "Read packet length err\n"); return -1; } // 2. 读取指定长度数据 data = client->readAll( ntohl(dwLen) ); return handle(data); }
3. 上面两种混合
类似http,redis协议实现
http:
HTTP/1.1 200 OK\r\n
Content-Length: 490\r\n
\r\n
alert('hello')
redis:
请求:
*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nhello\r\n
*3\r\n *表需多条批量回复,3参数个数
$3\r\nSET\r\n $表示字符串,\r\n分界符
响应:
+OK\r\n +/-/:/$ 首字符表回复类型