以前写过一篇用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封装版本,请留下您的邮箱,也欢迎与我交流。
分享到:
相关推荐
1、资源内容地址:https://blog.csdn.net/abc6838/article/details/143720369 2、数据特点:今年全新,手工精心整理,放心引用,数据来自权威,且标注《数据来源》,相对于其他人的控制变量数据准确很多,适合写论文做实证用 ,不会出现数据造假问题 3、适用对象:大学生,本科生,研究生小白可用,容易上手!!! 4、课程引用: 经济学,地理学,城市规划与城市研究,公共政策与管理,社会学,商业与管理
CPPC++_更好的Windows字体渲染
10018
cppc++
二环北路东段欣心家园小区商业B段(中石油加油站东邻).m4a
cppc++
C2005
Python课程设计之高校教务系统
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
10023
使用QUndoStack撤销栈实现QTreeWidget删除item及撤销、重做
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
Python课程设计之飞机大战3.zip
SpringBoot分布式事务
CPPC++_tensorort for yolo系列YOLOv10YOLOv9YOLOv8YOLOv7YOLOv6Y
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
收录了「IT无知君」CSDN博客中涉及的Java项目源码,还有许多的开发工具类,都是我自己在用在不断维护的,需要请进!
CPPC++_更新你的CFW作弊码固件,更直接地从你的任天堂交换机
test-dadfateq