完成端口中存在大BUG

batizhou 2007-02-15 11:10:20
今天用完成端口做测试时,发现连接A有可能收到连接B的数据。出错情况如下:
B连接的SOCKET号为992,B连接在做大量收发数据后closesocket。
若A连接建立时的SOCKET号也为992,这时A有可能会收到本该发给B的数据。

发生这种错误的概率比较小,我估计关闭B套接口时,内核中没能把已经投递到完成队列中的与992套接口相关的东东给清除掉,此时新的992套接口又被建立,那么新的套接口将有可能收到老的事件通知。

说句实话,本人觉得微软的IOCP设计的实在是有点垃圾,关闭套接口后不把东西清理干净。设计者初衷是想充分利用多线程的优势,但多线程造成的后果是很多事件的顺序根本得不到保证。而且还要加大量的锁,不仅增加了程序复杂度,而且锁加多了,多线程的优势也就没有了。

我用epoll写的网络组件,效率之高,CPU占用率之低,程序之简洁,隐藏BUG之少,都是IOCP无法比拟的。
...全文
743 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
贵子潘 2007-09-01
  • 打赏
  • 举报
回复
去拜读下楼上的大作
龙凤呈祥焱 2007-08-31
  • 打赏
  • 举报
回复
从理论上讲,完成端口应该不会出现这么弱智的错误。完成端口从NT3.5就有了,如果真有楼主所说的问题。那早就有人提交BUG了。
初步估计是楼主对完成使用不熟悉造成的。

多线程要在多CPU上才能体现优势,单CPU上,多线程没多大优势的。
fengge8ylf 2007-08-31
  • 打赏
  • 举报
回复
但多线程造成的后果是很多事件的顺序根本得不到保证。而且还要加大量的锁,不仅增加了程序复杂度,而且锁加多了,多线程的优势也就没有了。
------------------------------
我也发现这个问题了
denglibo 2007-08-31
  • 打赏
  • 举报
回复
socket唯一性问题

正常情况下 SOCKET套结字值是唯一的,但是操作系统在分配socket值时有随机性,最近关闭的socket值可能重新分派给一个刚刚建立的新的socket.,尤其在大并发短连接的情况下。一个健壮的服务器IOCP网络库必须要考虑socket唯一性的问题,由于IOCP的排队机制,意味着当你调用closesocket关闭socket后,IOCP队列中可能仍然堆积了该socket的一些 I/O completion packet,而此时,刚关闭的socket值又分派给一个刚刚建立的socket,所以,你必须对GetQueuedCompletionStatus获取到的I/O completion packet小心翼翼处理,避免出现数据混乱,然而,最好的方式等到所有I/O completion packet返回后才调用closesocket关闭该socket。

全文见拙作 http://libo.deng.blog.163.com 《编写大容量和健壮的服务器系列—处理IOCP连接关闭》一文
草鞋工 2007-08-30
  • 打赏
  • 举报
回复
谁这么无聊居然顶了个老贴上来,BS之
simonlx 2007-08-30
  • 打赏
  • 举报
回复
mark
batizhou 2007-03-05
  • 打赏
  • 举报
回复
to OldProgrammer()
我所说的9000万个连接不是同时连接,而是建立连接的次数,我的测试程序发送一会数据会断开并重联。Windows 2000 Server或2003在支持大容量网络连接方面性能要好于XP很多。
------------------------------

to DentistryDoctor(不在无聊中无奈,就在沉默中变态)
对于Web Server,如IIS,IOCP比epoll好用,要说写个网游服务器,epoll比IOCP好用,两者各有所长吧。

DkMoggy 2007-03-05
  • 打赏
  • 举报
回复
同时连接9000万是不可能的
DentistryDoctor 2007-03-05
  • 打赏
  • 举报
回复
个人并不这么觉得。
在于你自己如何利用了,你自己的代码如何写得了。

不可否认,epoll也是一种很好的模型,但不能因此否定IOCP.
OldProgrammer 2007-03-05
  • 打赏
  • 举报
回复
To:batizhou(batizhou)

abomber2(走来走去)
没有对 错误做处理而由用socket来区分不同的socket 存在设计错误
------------------------------------------------------------
你没看清我描述的问题,我没有用socket号来关联对象,这种错误我不太可能犯。

CancelIO我调过了。

我已经跑了大概有15个小时了,现在一切正常,总共有9000万连接,收发包数量已经把DWORD走了一轮多了。
----------------------------------------------------------------------------------


我在XP 512M内存,客户和服务器在一个机器上做测试,服务器端是ACCEPT,然后等待接受,客户端是CONNECT成功后,发送一个简单的数据,最后连接到3900多不到4000就连接不上了,请问这是什么原因,你是怎么写的代码?你怎么能连接到9000万多,资源能够用吗
coolzdp 2007-02-17
  • 打赏
  • 举报
回复
过年节分
batizhou 2007-02-16
  • 打赏
  • 举报
回复
microyzy(分也许不少,但别误会俺是高手)
大过年的0分贴,BS楼主~~
-------------------------------------------
响应一下,给点分,呵呵
batizhou 2007-02-16
  • 打赏
  • 举报
回复
abomber2(走来走去)
没有对 错误做处理而由用socket来区分不同的socket 存在设计错误
------------------------------------------------------------
你没看清我描述的问题,我没有用socket号来关联对象,这种错误我不太可能犯。

CancelIO我调过了。

我已经跑了大概有15个小时了,现在一切正常,总共有9000万连接,收发包数量已经把DWORD走了一轮多了。
microyzy 2007-02-16
  • 打赏
  • 举报
回复
大过年的0分贴,BS楼主~~

俺既没有用过IOCP,也没用过epoll,就8评论二者之孰是孰过,但lz说的问题,即使存在,应该和IOCP也没有关系,是TCP协议栈上的问题罢
Jazzlover 2007-02-16
  • 打赏
  • 举报
回复
试一下 closesocket 之前调用 CancelIo
abomber2 2007-02-16
  • 打赏
  • 举报
回复
不是 icop的问题 是你设计的问题!

没有对 错误做处理而由用socket来区分不同的socket 存在设计错误

IOContext对象设计不合理
lnp 2007-02-15
  • 打赏
  • 举报
回复
这时A有可能会收到本该发给B的数据
----------------------------------------
如果是用 TCP 出现这种问题, 除非你的发送端逻辑问题;而且这种问题与 IOCP 无关,如果逻辑有问题,这种问题用别的网络模型也会出现。
Analyst 2007-02-15
  • 打赏
  • 举报
回复
IOCP的架构确实设计的很差,远没有epoll模型来得简洁。
batizhou 2007-02-15
  • 打赏
  • 举报
回复
我的测试程序每秒会有数百次连接和断开,我写程序时不会考虑SOCKET到底是什么值,但每次出现这种情况时,新建立的SOCKET收到的数据不是其他的,而恰好是相同值的SOCKET在上次关闭前应该收到的数据。

这种情况在其他IO模型中是否会出现我不清楚,但IOCP中的确会出现,而且现在我也找到办法来避免这种情况的发生,经过一些特殊步骤后,不会再出现这种情况了。
batizhou 2007-02-15
  • 打赏
  • 举报
回复
我可以确定至少不是我程序的问题,而是系统的问题,否则不可能每次出问题时,SOCKET都那么巧是一样的。

18,356

社区成员

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

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