`
qepwqnp
  • 浏览: 106378 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

再次封装IOCP的收获

阅读更多

以前写过一篇用python封装IOCP的文章,这几天因朋友需要,再一次封装了iocp接口。这一次我并不是简单的把原有代码拿过来简单的修修改改,基本上是推到重来。改正第一次封装时的许多缺点,同时修正了许多bug,再回首看以前的代码,感觉自己在进步。这次封装iocp,收获了以下几点知识:

1. 数据的重复投递。一般情况下,一个Socket句柄在同一时刻最多只能有一次WSASend与SWARecv,如果多次投递WSASend或者WSARecv,有可能造成数据的重复发送或重复接收。我一般为每个Socket创建两个buffer,一个用于发送数据(send buffer),别一个用于接收数据(recv buffer),当send buffer中有数据的时候,就投递WSASend,如果send buffer为空,则不投递,且保证任何时刻该Socket只有一次WSASend投递。同样,当recv buffer满的时候,不投递WSARecv,如果recv buffer有空闲空间,就投递WSARecv投,且保证同一时刻该Socket只有一次WSARecv递。

2. 如果WSARecv或WSASend投递失败,将不会接收到通知。如:if (WSARecv(sock, …) == SOCKET_ERROR && err_no != WSA_IO_PENDING) { // 投递失败,不会为这次投递发送通知。 }

3. 关于连接断开时接收到的通知。如果iocp检测到Socket连接已经断开,程序马上会收得到通知,而且有时候会收到不至一次通知,这取决于你在该socket上投递WSASend与WSARecv的次数。例如你在一个socket上投递了一次WSASend与一次WSARecv,在这两次投递还没有被完成时,如果socket断开了连接,那么GetQueuedCompletionStatus()将会收到两次通知。一般情况下,我们会为每个连接准备两个重叠IO结构(Overlapped struct),一个用于接收数据,另一个用于发送数据。当连接断开的时候,就应该正确地释放这些资源。

4. 对于Socket的管理。一般情况下,使用字典或者列表来管理所有的连接。以字典为例,当连接创建的时候,将连接加入到字典中,而连接断开的时候,将连接从字典中移除。因为IOCP可能有多个工作者线程,所以在执行上述操作时,应该保证操作的原子性,也就是多线程同步问题。例如:一个工作者线程正在对一个连接投递WSASend操作,而同时另一个工作者线程检测到这个连接已经断开,并将该连接从字典中移除,并释放了与该连接相关的资源,此时就会出现不可预知的情况。

5. 关于IOCP的性能。网上有一些文章说IOCP能同时处理上万个连接,但我写的IOCP程序根本无法达到这个数,于是对IOCP的性能进行了怀疑。其实,经过我的调试发现,IOCP的效率确实高,处理上万个连接应该没问题,至于为什么自己的程序没有能达到这个数量级,我觉得主要是我的程序要维护成百上千个连接的缘故。我用hash_map来管理所有的连接,在程序中经常要根据key来获取相应的数据结构,如果很频繁的调用这样的操作,是会引起性能问题的。可以写一个简单的C++程序来感受一下:

// 下面这段代码在VC下是很占资源的
map<int, int> dict;
for (int i = 0; i < 1000; ++i)
	dict[i] = i;

while (1) {
	for (int i = 0; i < 1000; ++i) {
		dict[i];
	}
	Sleep(10);
}

上面这些内容是我第二次封装iocp所尝到的东西,网上还有许多关于iocp的好文章可供参考。如果您需要iocp的python封装版本,请留下您的邮箱,也欢迎与我交流。

分享到:
评论

相关推荐

    ACE IOCP封装

    基于ACE的IOCP封装,只要继承iocp_server 类就可以实自己的服务器了。 wonderful.

    iocp_c++11.rar_C++ iocp_IOCP 封装_c++ 异步框架_c++iocp封装_spentp2t

    iocp异步通信封装,适合中小型并发服务器框架,性能经测试还可以

    windows iocp网络通讯库封装

    windows iocp网络通讯库封装

    Iocp_V7,IOCP封装类(DLL)第七次改版.

    由于兼容问题,不再使用Lib形式的封装,使用DLL 去掉0缓冲,接收数据大小有限制 IOCP只负责接收前256字节,剩下的根据自定义协议(肯定知道包的大小)再recv 添加Connect函数,所以此IOCP不仅可以作为服务端,同时也可以作为...

    iocp封装demo

    经典的iocp 封装类, 放在这里以后应该能用上。很简单易懂的。

    公认不错的IOCP封装类

    我们的一个项目的服务器端通信层,IOCP类是在此基础上写的,使用了近半年,并发量不大,1k上下,(不过曾做过压力测试,10k的并发量没有问题)还算比较稳定,基本上满足需求。

    IOCP封装类,用VC6.0封装的

    IOCP_V5.rar(20110208) 服务端: 取消监听线程,采用AcceptEx异步接收套接字,效率更高 支持大量并发连接不丢包 压力测试后尚未发现内存泄露 IOCP_V4.rar(20110208) 服务端: 代码更加稳定,取消监听线程的异常处理 删减...

    高度封装的 IOCP库

    决定写一个IOCP,封装的很好的,这是一个库,请在VC2010下编译。 客户端和服务器都适用,但是只完成了TCP的部分,没有完成UDP的部分。 面向对象的方式编写。 包含连接器,内存管理,等模块。 无协议模块

    IOCP封装类。

    网上一个朋友的IOCP类,我现在在研究IOCP,但是发现这个类有些缺陷,但是不知道如何修改一遍提高性能,还有就是我做压力测试,发现这个类有内存泄露,总是以4K的大小在增长,希望懂IOCP的朋友帮忙看看~~

    一个对IOCP进行封装的DLL

    一个老外写的IOCP的dll。对于不会完成端口编程的人只需要进行加载DLL,和调用接口函数就能完成服务器编程。很难找的代码哦。资源里面有文档和例子程序

    一个IOCP模型的socket封装类

    A simple application using IO Completion Ports and WinSock。老外写的IOCP封装类,使用了线程池和内存池。很不错的东西.资源里面有文档和例子程序

    IOCP.rar_IOCP_IOCP 封装_visual c

    封装了IOCP逻辑,条理清晰,包含例子.

    iocp-epoll

    iocp-epoll的几个例子,提供参考。 其中,iocp包含了几种使用方式,同步异步处理方式, epoll为linux下面使用,编译时可以使用下面简单命令, g++ -p -g -o hhh ***.cpp -l pthread

    VC6 IOCP封装类

    一个VC++6.0 封装的IOCP类,有丰富的注释,能较快的借鉴和使用。

    经过封装的IOCP完成端口模型客户端

    经过封装的IOCP完成端口模型客户端。 主要功能有发送普通文本数据,传输文件,下载文件

    使用IOCP完成端口和SOCKET封装的成熟异步TCP类

    使用IOCP完成端口和SOCKET封装的异步TCP类。 支持客户端和服务器的常用TCP接口:绑定Bind、监听Listen、接收Recv、连接Conn、发送Send、关闭Close。所有接口均使用异步回调的方式处理,内部实现使用Windows下性能...

    iocp封装类

    iocp完成端口的封装,使用TCP的IOCP实现,可以传送大消息包、文件,同一客户端可以同时发送多个文件 // 1、用TClients创建一个对象,pClients // 2、调用pClients-&gt;CreateClient(...)函数,参数1、2是要连接的服务端...

    IOCP 完成端口模型简单封装

    采用IOCP模型简单封装的网络通信模型,可以用来学习交流使用。代码里面有些是根据个人业务修改的部分,也可以自己修改成所需,还有一些功能没有完善,不过可以使用。

    IOCP.rar_IOCP_IOCP 封装_传输文件_完成端口_服务器

    源码使用了高级的完成端口(IOCP)技术,该技术可以有效地服务于多客户端。代码封装了IOCP并提供了一个简单的echo版本的可以传输文件的客户端/服务器程序

    把Winsock IOCP完成端口模型封装成c++类.zip

    把Winsock IOCP完成端口模型封装成c++类.zip

Global site tag (gtag.js) - Google Analytics