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