tcp 粘包

阅读更多

由于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)