之前tcp方面写的很少,udp写的倒是不少,所以这次写网络版程序的时候遇到了很大的问题,开始认为网络并发方面iocp完成端口肯定是最有优势架构,于是开始拜读王艳平《windows网络与通信程序设计》那本书,看个8成懂,开始进行测试--iocpsys,发现线程池处理时包的顺序在设置线程数2以上的时候出错,即如果客户端不等待发送大量数据包,书中给的链表数据结构包括其处理不能够处理好包号排序的问题,不知有没有具体调试过这个程序的大虾,codeproject上有个巨复杂的,而且不能判断恶意连接;继而测试IOCPDemo这个单线程程序,包的顺序不会出错了,但是经过50000-1000000的数据包的测试发现会有少量数据包丢失,非常郁闷,测试环境局域网,不应该呀,反复调整程序结果依然,网上查了下,有大虾遇到有此种问题存在,但没有找到可行的解决方案;弃之使用最简单的WSAAsyncSelect模型,windows消息大大削弱了网络接收的能力,太慢了,丢包倒是没有发现;弃之使用select模型,发现此种模型在效率和丢包上都是不错的,测试发现没有丢包发生。关于tcp的完成端口,有哪位大侠解决了服务器端接受包的顺序问题及丢包问题,参考哪个例子,msdn上代码好像比较少多,欢迎指教,[email protected]、qq:313668429
大概看了一下,也看了一下里边的例子,但没有调试,在网上找了几个例子还是存在包序问题,即多个工作线程开启,客户端for循环无等待发包,不知是否和TCP的粘包问题有关,包括丢包,有可能是有的数据未解析出来
应该是对方发送时候就出现错误没有发过来,并不是才传输过程丢的,检查对方对发送结果有错误判断.
我就发现在GetNextReadBuffer这个函数里面是有错的,我改了一下,成下面这样
CIOCPBuffer *CIOCPServer::GetNextReadBuffer(CIOCPContext *pContext, CIOCPBuffer *pBuffer)
{
if(pBuffer != NULL)
{
// 如果与要读的下一个序列号相等,则读这块缓冲区
if(pBuffer->nSequenceNumber == pContext->nCurrentReadSequence)
{
return pBuffer;
}
// 如果不相等,则说明没有按顺序接收数据,将这块缓冲区保存到连接的pOutOfOrderReads列表中 // 列表中的缓冲区是按照其序列号从小到大的顺序排列的 pBuffer->pNext = NULL;
CIOCPBuffer *ptr = pContext->pOutOfOrderReads;
CIOCPBuffer *pPre = NULL;
while(ptr != NULL)
{
if(pBuffer->nSequenceNumber < ptr->nSequenceNumber)
break;
pPre = ptr;
ptr = ptr->pNext;
}
if(pPre == NULL) // 应该插入到表头
{
pBuffer->pNext = pContext->pOutOfOrderReads;
pContext->pOutOfOrderReads = pBuffer;
}
else // 应该插入到表的中间
{
pBuffer->pNext = pPre->pNext;
//原来的代码是下面这一行
//pPre->pNext = pBuffer->pNext; //改成现在这样
pPre->pNext = pBuffer;
}
} // 检查表头元素的序列号,如果与要读的序列号一致,就将它从表中移除,返回给用户
CIOCPBuffer *ptr = pContext->pOutOfOrderReads;
if(ptr != NULL && (ptr->nSequenceNumber == pContext->nCurrentReadSequence))
{
pContext->pOutOfOrderReads = ptr->pNext;
return ptr;
}
return NULL;
}但是这个例子怎么说,就是比较简单