使用过shenyi0106的【IOCP_API之TCP服务器编程】的进来看下,也请shenyi0106帮助解答下问题... 本帖最后由 wswwxk 于 2011-10-31 23:04:16 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 自己顶下,怎么不可以发200分的帖子呢?wince版块都可以,呵呵 感谢帮助俺测试,呵呵…… 最近换了工作,刚刚入职,很多事情要弄,所以没有时间来逛CSDN了,对已你发现的问题,我也有过这样的大负载测试,我测试的最大负载是11000PPS(每秒11000个包),每个包是1K,从流量监测工具上看到的是10MB/s的流量,而且也做了相应的长时间负载测试(>=20分钟),均表现正常(内存,CPU,网络都表现正常)。 但是有一点我没有说到,就是在大负载情况下,突然关闭服务器,可能会造成内存泄露,这是由于采用了内存池的技术,并且IOCP是异步通知的特性,也就是说,有些已经投递内存在突然关闭服务器时,没有来得及得到完成通知,导致没有完成相关的内存释放,但是这仅仅会发生在大负载且突然关闭的情况下,正常运行不会出现这类问题。 还有一点,你打开源码,将代码中的所有名称相同的结构体的名称改一下,改成不同明的(代码中也要做相应修改),然后再重新编译。我最经发现好像这些同名的结构体虽然在不同的引用文件中,但是要想存在一些不可预知的运行时冲突(会导致sizeof计算错误),你修改一下,然后再试试。 大致就是这些情况,有什么问题,请及时和我联系,最好QQ联系,我也好及时回应(虽然可能有事不能立即回应,但是最起码我知道这事了,呵呵) 内存泄露的高手. 怕怕.我还是用自己的iocp. 感谢shenyi0106的回答,我加你QQ了,但是没反应,加我吧,287336900,呵呵,我也好方便请教你 codeproject上面有几个完成端口例子,没有内存问题,只是测试的话用用没问题。商用的话还要仔细完善一下。 shenyi0106提供了最新的demo,但是长时间运行内存还是有问题,shenyi0106最近没时间,大家有空的可以一起研究下啊 强烈建议进行单机测试最大流量....客户全速发送8K接收服务器回复8K, 看看1s内能够做多少次. 多开客户端以后每个客户端是多少次进行测试...期待发布测试结果... 针对内存泄露问题,我做了个测试,以下是测试结果截图:测试时间: 1个小时测试客户端数量: 20个测试包大小: 1K测试方法: 本机pingpong测试(客户端发出起始包,服务器和客户端收到包均发送给对方)每秒钟包数(pps): 13800~14200之间流量: 没做统计,可以通过PPS和包大小计算出来以下是测试1小时后的截图:内存无变化,没有检测到内存泄露问题以上是我的测试结果,仅供参考 针对内存泄露问题,我做了个测试,以下是测试结果截图:测试时间: 1个小时测试客户端数量: 20个测试包大小: 1K测试方法: 本机pingpong测试(客户端发出起始包,服务器和客户端收到包均发送给对方)每秒钟包数(pps): 13800~14200之间流量: 没做统计,可以通过PPS和包大小计算出来以下是测试1小时后的截图:内存无变化,没有检测到内存泄露问题以上是我的测试结果,仅供参考 终于有个像样一点的IOCP测试了...shenyi0106, 你好像漏了你的机器配置 感谢shenyi0106的测试,我可能没说清楚,我两台PC连接通信,服务端的在性能属性里面的PF使用率没怎么变化,说明动态申请的都没问题,但是在客户端的任务管理器里面的PF使用率,会增加,只是增加的比较慢,我现在参考你的例子,参考IOCP_API,实现的客服端,问题应该在你封装的客户端的接受回调函数里面的动态申请的内存问题,我在确认下,把问题找出来,完善下IOCP_API,呵呵 非常感谢各位……pe2140(1.6G),2G内存,本机测试没写网络(库文件中带有局域网环境下的测试报告)客户端封装没有严格测试(但是从理论来说是没有问题的),你如果怀疑有内存泄露点,可以通过调试或者内存检测工具来检测 问题貌似找到了,客户端接收定义的事件,在函数退出时没有释放,加上WSACloseEvent(Overlapped.hEvent);等待shenyi0106的确认 非常感谢,的确漏了一句关闭事件的代码//循环接收数据,直到数据接收完毕 while(RecvTotalBytes < nDataTotalLen) { //调整接收缓冲区 Flags = 0; RecvBytes = 0; DataBuf.len = DATA_BUFSIZE - RecvTotalBytes; DataBuf.buf = ccpBuffer + RecvTotalBytes; //复位事件,继续接收 WSAResetEvent(Overlapped.hEvent); //接收数据 if (WSARecv(hSock, &DataBuf, 1, &RecvBytes, &Flags,&Overlapped, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != ERROR_IO_PENDING) { TRACE("WSARecv failed with error [%ld]\n",WSAGetLastError()); return FALSE; } } //等待接收完成 if(WSAWaitForMultipleEvents(1, &(Overlapped.hEvent), TRUE, INFINITE, TRUE) == WSA_WAIT_FAILED) { TRACE("WSAWaitForMultipleEvents failed with error [%ld]\n",WSAGetLastError()); //关闭事件 WSACloseEvent(Overlapped.hEvent); GlobalFree(ccpBuffer); return FALSE; } //接收完成,查询接收状态 Flags = 0; RecvBytes = 0; if(WSAGetOverlappedResult(hSock, &Overlapped,&RecvBytes, FALSE, &Flags) == FALSE) { TRACE("WSAGetOverlappedResult failed with error [%ld]\n",WSAGetLastError()); //关闭事件 WSACloseEvent(Overlapped.hEvent); GlobalFree(ccpBuffer); return FALSE; } //调整接收的字节数 RecvTotalBytes = RecvTotalBytes + RecvBytes; }//****************************************************//***********这里漏了这句****************************** //关闭事件 WSACloseEvent(Overlapped.hEvent);//****************************************************//**************************************************** //分析数据接收到的数据 BOOL bFlag = PacketAnalyse(hSock,ccpBuffer,RecvTotalBytes,&(*cchRetBuf),nRetLen,nId); //接收数据 if (WSARecv(hSock, &DataBuf, 1, &RecvBytes, &Flags,&Overlapped, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != ERROR_IO_PENDING) { TRACE("WSARecv failed with error [%ld]\n",WSAGetLastError()); return FALSE; } }返回之前是不是要添加//关闭事件 WSACloseEvent(Overlapped.hEvent); GlobalFree(ccpBuffer);呢? 自己顶下,怎么不可以发200分的帖子呢?wince版块都可以,呵呵 不需要,看看我给你的例子,在RecvPacket后面,如果返回成功,是需要调用ReleasePacket释放这个包的 codeproject上面有几个完成端口例子,没有内存问题,只是测试的话用用没问题。商用的话还要仔细完善一下。 测试过,有很多的问题,还是shenyi0106的好点 注意!!这是pingpong测试,发送依赖接收 错误 2 error C2664: “IOCPInitServer”: 不能将参数 1 从“void (__cdecl *)(SOCKET,char *,int)”转换为“NOTIFYPROC” 去掉客户端的里面发送的setsockopt设置就可以了,但是包数量明显减少,但是从360速度提示,又是正常的,这还有继续测试 我自己重新写了客户端,使用选择模式,没有设置setsockopt的缓冲区,现在基本上正常了,谢谢大家,东西还有继续完善,先结贴吧 测测双工吧,应该存在崩溃级别的bug 最这个不太熟悉,感觉使用ACE挺省心的 给你一个IOCP Framework 代码 http://code.google.com/p/iocpframework/ 可以看看这个IOCP http://code.google.com/p/iocpframework/ 100分 菜鸟毕设求助,图像处理 如何在C*Doc文件里获得(创建)CClient对象? 系统主题风格影响了CListCtrl的窗口拖动的实现,怎么办? VC的智能提示信息是保存在什么文件里的? MFC高手请进,请问MFC如何传递实参给消息处理函数? 熟悉wise的朋友请帮帮忙!谢谢! IDispatch error #3105,为什么??? 请详细介绍InvokeHelper 转化成tiff 请问如何将窗口最小画到Windows右下角(象QQ那样),而非到任务栏中? VS2008中 如何给类CMFCMenuBar菜单项关联图标??? 静态库调用问题
最近换了工作,刚刚入职,很多事情要弄,所以没有时间来逛CSDN了,
对已你发现的问题,我也有过这样的大负载测试,我测试的最大负载是11000PPS(每秒11000个包),每个包是1K,从流量监测工具上看到的是10MB/s的流量,而且也做了相应的长时间负载测试(>=20分钟),均表现正常(内存,CPU,网络都表现正常)。
但是有一点我没有说到,就是在大负载情况下,突然关闭服务器,可能会造成内存泄露,这是由于采用了内存池的技术,并且IOCP是异步通知的特性,也就是说,有些已经投递内存在突然关闭服务器时,没有来得及得到完成通知,导致没有完成相关的内存释放,但是这仅仅会发生在大负载且突然关闭的情况下,正常运行不会出现这类问题。
还有一点,你打开源码,将代码中的所有名称相同的结构体的名称改一下,改成不同明的(代码中也要做相应修改),然后再重新编译。我最经发现好像这些同名的结构体虽然在不同的引用文件中,但是要想存在一些不可预知的运行时冲突(会导致sizeof计算错误),你修改一下,然后再试试。 大致就是这些情况,有什么问题,请及时和我联系,最好QQ联系,我也好及时回应(虽然可能有事不能立即回应,但是最起码我知道这事了,呵呵)
测试客户端数量: 20个
测试包大小: 1K
测试方法: 本机pingpong测试(客户端发出起始包,服务器和客户端收到包均发送给对方)
每秒钟包数(pps): 13800~14200之间
流量: 没做统计,可以通过PPS和包大小计算出来以下是测试1小时后的截图:内存无变化,没有检测到内存泄露问题以上是我的测试结果,仅供参考
测试客户端数量: 20个
测试包大小: 1K
测试方法: 本机pingpong测试(客户端发出起始包,服务器和客户端收到包均发送给对方)
每秒钟包数(pps): 13800~14200之间
流量: 没做统计,可以通过PPS和包大小计算出来以下是测试1小时后的截图:内存无变化,没有检测到内存泄露问题以上是我的测试结果,仅供参考
感谢shenyi0106的测试,我可能没说清楚,我两台PC连接通信,服务端的在性能属性里面的PF使用率没怎么变化,说明动态申请的都没问题,但是在客户端的任务管理器里面的PF使用率,会增加,只是增加的比较慢,
我现在参考你的例子,参考IOCP_API,实现的客服端,问题应该在你封装的客户端的接受回调函数里面的动态申请的内存问题,我在确认下,把问题找出来,完善下IOCP_API,呵呵
pe2140(1.6G),2G内存,本机测试没写网络(库文件中带有局域网环境下的测试报告)客户端封装没有严格测试(但是从理论来说是没有问题的),你如果怀疑有内存泄露点,可以通过调试或者内存检测工具来检测
等待shenyi0106的确认
非常感谢,的确漏了一句关闭事件的代码//循环接收数据,直到数据接收完毕
while(RecvTotalBytes < nDataTotalLen)
{
//调整接收缓冲区
Flags = 0;
RecvBytes = 0;
DataBuf.len = DATA_BUFSIZE - RecvTotalBytes;
DataBuf.buf = ccpBuffer + RecvTotalBytes;
//复位事件,继续接收
WSAResetEvent(Overlapped.hEvent);
//接收数据
if (WSARecv(hSock, &DataBuf, 1, &RecvBytes, &Flags,&Overlapped, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
TRACE("WSARecv failed with error [%ld]\n",WSAGetLastError());
return FALSE;
}
}
//等待接收完成
if(WSAWaitForMultipleEvents(1, &(Overlapped.hEvent), TRUE, INFINITE, TRUE) == WSA_WAIT_FAILED)
{
TRACE("WSAWaitForMultipleEvents failed with error [%ld]\n",WSAGetLastError());
//关闭事件
WSACloseEvent(Overlapped.hEvent);
GlobalFree(ccpBuffer);
return FALSE; }
//接收完成,查询接收状态
Flags = 0;
RecvBytes = 0;
if(WSAGetOverlappedResult(hSock, &Overlapped,&RecvBytes, FALSE, &Flags) == FALSE)
{
TRACE("WSAGetOverlappedResult failed with error [%ld]\n",WSAGetLastError());
//关闭事件
WSACloseEvent(Overlapped.hEvent);
GlobalFree(ccpBuffer);
return FALSE;
} //调整接收的字节数
RecvTotalBytes = RecvTotalBytes + RecvBytes;
}//****************************************************
//***********这里漏了这句******************************
//关闭事件
WSACloseEvent(Overlapped.hEvent);
//****************************************************
//**************************************************** //分析数据接收到的数据
BOOL bFlag = PacketAnalyse(hSock,ccpBuffer,RecvTotalBytes,&(*cchRetBuf),nRetLen,nId);
if (WSARecv(hSock, &DataBuf, 1, &RecvBytes, &Flags,&Overlapped, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
TRACE("WSARecv failed with error [%ld]\n",WSAGetLastError());
return FALSE;
}
}
返回之前是不是要添加
//关闭事件
WSACloseEvent(Overlapped.hEvent);
GlobalFree(ccpBuffer);
呢?
谢谢大家,东西还有继续完善,先结贴吧