关于IOCP的WSANOBUFS问题

abuseyoudna1981 2009-05-30 12:19:56
简单的写了个IOCP的例子,相信遇到很多人都遇过的问题,就是出现WSANOBUFS,只是简单的接受连接。服务器和客户端都在同一机子上面,但成功连接四千个连接后。便出现WSANOBUFS的错误。不知道什么愿意,没有接受,没有发送,只是接受连接。用的是AcceptEx,

bSucceed = m_lpfnAcceptEx(m_sListen, pIoData->sClient, pIoData->buf, 0, sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16, &dwBytes, &pIoData->ol);

按道理来说,我用了WSAEventSelect,注册了FD_ACCEPT事件,只有激后再投递AcceptEx,但依然有WSANOBUFS,已经把AcceptEx第四个参数改为0,但依然有错,望高手指教。
...全文
150 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
auly403 2009-05-31
  • 打赏
  • 举报
回复
LZ换个服务器的操作系统看看? 就可以连得更多了,
Jurang 2009-05-31
  • 打赏
  • 举报
回复
很同意楼上的观点。
Leo_red 2009-05-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 stjay 的回复:]
应该是同时投递太多IO操作了
包括WSASend和WSARecv的

每当我们重叠提交一个WSASend或WSARecv操作的时候,
其中指定的发送或接收缓冲区就被锁定了。
当内存缓冲区被锁定后,
将不能从物理内存进行分页。
操作系统有一个锁定最大数的限制,
一旦超过这个锁定的限制,
那么就会产生WSAENOBUFS 错误了。
[/Quote]

我也同意,毕竟你每构造一个客户端连接就会对应分配一个Overlapped结构,系统应该会对所有已经分配的结构纳入什么队列来管理。
如果结构数很多超出上限,就会报这种错误。
不过过我以前测试时,4000客户端同时连接并且收发数据都是正常的,所以一个是机器的配置也影响一些吧?
另外LZ检查一下代码,看看在分配客户端对象时会不会有些内存泄漏的问题。
abuseyoudna1981 2009-05-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 unsigned 的回复:]
引用 9 楼 abuseyoudna1981 的回复:
是XP SP2

XP SP2有连接限制
[/Quote]

那能知道连接限制数是多少吗?那XP的其他版本也会有这种限制?我记忆中,别人用XP,也能有1W以上连接的呀。
僵哥 2009-05-31
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 abuseyoudna1981 的回复:]
是XP SP2
[/Quote]
XP SP2有连接限制
abuseyoudna1981 2009-05-30
  • 打赏
  • 举报
回复
物理内存是够的,试过把SOCKET的SND_BUF, RCV_BUF关了。连接数都没有增加一个。。。。只是单纯的连接与接受连接,在同一部机子上测试的,但分开机子,依然是这个数。有点郁闷
hhwei1985 2009-05-30
  • 打赏
  • 举报
回复
学习
hhwei1985 2009-05-30
  • 打赏
  • 举报
回复
学习
abuseyoudna1981 2009-05-30
  • 打赏
  • 举报
回复
是XP SP2
僵哥 2009-05-30
  • 打赏
  • 举报
回复
OS版本?如果是winxp可能是连接数限制.理论上来讲,如果单纯建立连接,在不进行额外的核心内存占用的情况下可以连上六万多个连接.
abuseyoudna1981 2009-05-30
  • 打赏
  • 举报
回复
操作的流程不复杂。就一个AcceptEx线程,负责投递AcceptEx请求,线程里面用WSAEventSelect来决定是否投递,一次投递多少个AcceptEx是可以调整的,1个到N个,都试过了,而且都是0字节投递,按道理来说,会马上释放掉锁住的内存,然后就是在IOCP线程为新连接调用CreateIOCompletionPort和投递WSARecv, 如果说WSARecv有可能影响,我把它注释了,连接数也一样没提升,基本都是3970连接数就出现WSAENOBUFS。。。。中间有使用内存池。
rularys 2009-05-30
  • 打赏
  • 举报
回复
底层的原因不清楚,只知道不同的系统下连接数会不一样
stjay 2009-05-30
  • 打赏
  • 举报
回复
AcceptEx两步的过程:接受连接和等待第一次数据
缓冲大小设为0后只接受连接
这样都出现WSAENOBUFS...
查看一下物理内存..
创建的socket也会占用非分页内存
stjay 2009-05-30
  • 打赏
  • 举报
回复
应该是同时投递太多IO操作了
包括WSASend和WSARecv的

每当我们重叠提交一个WSASend或WSARecv操作的时候,
其中指定的发送或接收缓冲区就被锁定了。
当内存缓冲区被锁定后,
将不能从物理内存进行分页。
操作系统有一个锁定最大数的限制,
一旦超过这个锁定的限制,
那么就会产生WSAENOBUFS 错误了。

18,357

社区成员

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

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