IOCP服务器连续发送的问题。

jenics 2013-02-16 10:20:29
比如说。在一个代码断里连续投递了5个WSASend给客户端(数据量也不大)

在客户端那边接收时,有可能只接收到了两条数据。(客户端没有使用IOCP,只是简单的winSock)

这种问题如何解决呢。还请大牛支支招。
...全文
269 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
jenics 2013-02-26
  • 打赏
  • 举报
回复
结贴了。谢谢各位的回答。估计真是粘包的问题。 容我回去在去研究研究。
  • 打赏
  • 举报
回复
没必要用iocp吧 用eventselect也不错啊
这不是鸭头 2013-02-17
  • 打赏
  • 举报
回复
你要自定义一个协议,来方便解包,解决TCP粘包的问题
Eleven 2013-02-17
  • 打赏
  • 举报
回复
引用 楼主 jenics 的回复:
比如说。在一个代码断里连续投递了5个WSASend给客户端(数据量也不大) 在客户端那边接收时,有可能只接收到了两条数据。(客户端没有使用IOCP,只是简单的winSock) 这种问题如何解决呢。还请大牛支支招。
你接收端的代码是怎么写的?
cyfage 2013-02-17
  • 打赏
  • 举报
回复
我自己的简单拆包代码:

struct myWSAPack //标准数据包结构
{
	int WSALen; //数据包长度
	int WSAId; //数据包ID
	char Buffer[MYWSA_BUFSIZE]; //数据包内容
};

int myWSAClient::UnPack(char *Buffer, int Lenth)
{
	if (Lenth <= 0 || NULL == Buffer)
	{
		return -1;
	}

	int Len = Lenth;
	char *lpHead = Buffer;
	myWSAPack *lpPack = (myWSAPack*)lpHead;

	while (Len > 0)
	{
		if (lpPack->WSALen <= 0 || lpPack->WSALen > MYWSA_PACKSIZE)
		{
			sprintf_s(m_Log, sizeof(m_Log), "拆包出错:WSALen=%d", lpPack->WSALen);
			Log(m_Log);
			return -1;
		}

		if (Len < lpPack->WSALen)
		{
			sprintf_s(m_Log, sizeof(m_Log), "拆包出错:len=%d != lPHead->WSALen=%d", Len, lpPack->WSALen);
			Log(m_Log);
			return -1;
		}

		myWSACDATA data = {0};
		data.Lenth = lpPack->WSALen;
		memcpy(data.Buffer, lpPack, lpPack->WSALen);

		Len -= lpPack->WSALen;
		lpHead = lpHead + lpPack->WSALen;
		lpPack = (myWSAPack*)lpHead;

		myWSAPack *Pack = (myWSAPack*)data.Buffer;

		switch (Pack->WSAId)
		{
		case MYWSA_HEARTID:
			{
				myWSAPack rPack = {0};
				rPack.WSAId = MYWSA_HEARTRD;
				rPack.WSALen = MYWSA_HEADSIZE;

				::send(m_sConnect, (char*)&rPack, rPack.WSALen, 0);
			}
			break;
		case MYWSA_HEARTRD:
			{
				if (true == m_IsHearting)
				{
					for (int i = 0; i < MYWSA_HEARTLIMIT; ++ i)
					{
						if (0 == m_HeartCount[i])
						{
							m_HeartCount[i] = 1; //写入心跳记录
							break;
						}
					}
				}
			}
			break;
		default:
			{
				m_ReceiveQue.push(data);
				::PostMessage(m_MainHandle, m_MSGID, m_WPID, MYWSA_CRECEIVE);
			}
		}
	}

	return 1;
}
jenics 2013-02-16
  • 打赏
  • 举报
回复
补充:如果在服务器端 Sleep(300) 这样就好了。。 但是这样做并不是IOCP初衷。 到底是什么问题呢。。。搞了两周了。
youngwolf 2013-02-16
  • 打赏
  • 举报
回复
我的意思是,其实客户端是接收完整了的,只是没有考虑粘包问题,造成了消息丢失。
youngwolf 2013-02-16
  • 打赏
  • 举报
回复
客户端那边如果没有什么错误,那就是粘包了,数据接收了多少,一定要以接收长度为准,其它方式都有可能出错,比如你发一个字符串,在接收方绝不能用strlen来判断接收了多少字节。
shiter 2013-02-16
  • 打赏
  • 举报
回复
路过帮顶,共同学习,上点代码看看么

18,357

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧