tcp 粘包 丢包 解决方案

1、分析tcp粘包和丢包的原因

   发送数据的时候有  发送缓冲区senBuff,

   接收数据的时候有  接收缓冲区recvBuff,

   假如接收数据方一直不recv, 则recvBuff就会堆满, 这个时候tcp就会停止发送数据了。

   同样因为接收缓冲区的数据满了, 所以发送缓冲区也不会再就收发送方发来的消息。

2、解决方案

// 接收数据  处理年包 拆分包
int CEasyTcpClient::RecvData()
{
	//char szRecv[1024] = {};
	printf("RecvData, 11111");
	// 5 接收客户端请求
	int nLen = (int)recv(m_sock, m_szRecv, RECV_BUFF_SIZE, 0);
	if (nLen <= 0)
	{
		printf("<socket = %d>与服务器断开连接, 任务结束。 \n", (int)m_sock);
		return -1;
	}

	printf("client recv data , nLend = %d\n", nLen);

	//将收取到的数据拷贝到消息缓冲区
	memcpy(m_szMsgBuf + m_nLastPos, m_szRecv, nLen);
	//消息缓冲区的数据尾部位置后移
	m_nLastPos += nLen;
	//判断消息缓冲区的数据长度大于消息头DataHeader长度
	while (m_nLastPos >= sizeof(DataHeader))
	{
		//这时就可以知道当前消息的长度
		DataHeader* header = (DataHeader*)m_szMsgBuf;
		//判断消息缓冲区的数据长度大于消息长度
		if (m_nLastPos >= header->dataLength)
		{
			//消息缓冲区剩余未处理数据的长度
			int nSize = m_nLastPos - header->dataLength;
			//处理网络消息
			OnNetMsg(header);
			//将消息缓冲区剩余未处理数据前移
			memcpy(m_szMsgBuf, m_szMsgBuf + header->dataLength, nSize);
			//消息缓冲区的数据尾部位置前移
			m_nLastPos = nSize;
		}
		else {
			//消息缓冲区剩余数据不够一条完整消息
			break;
		}
	}
	return 0;
}

类似这样的大概思路就是  接收到数据存到一级缓冲区, 然后从一级缓冲区拷贝到二级缓冲区, 之后判断二级缓冲区长度是否大于包头长度, 如果大于包头长度就进行解析,  因为包头里面包含了完整消息协议的总长度。  这样就不会出现粘包和丢包的问题了。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值