欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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 +/-/:/$ 首字符表回复类型

 

 

 

 

相关标签: tcp redis