accept失败,报错10038

_小罗 2012-02-21 08:59:54
开发服务器程序,需要模拟几千个客户端,监听线程运行了一段时间之后,accept会失败,用wsagetlasterror获取的错误信息是10038,对非socket进行操作。
首先,网上说的可能是我什么地方调用了closesocket()函数,所以我在closesocket下面加了TRACE信息,打印了调用closesocket函数的所有的socket值,同时也TRACE了每次用于accept的监听socket值。但是我并没有对监听的socket进行closesocket()。

其次,我有的时候accept失败的时候我直接continue,下一次accept的时候的时候又可以了,然后过几次又会失败。

再次,我每次accept我都打印了监听socket值,不管正常异常,用于accept的值都是一样的。

还有,网上还有的说法是listen队列满了,但是如果是这个原因的话,是不是不应该是报10038的错误呢。

还有最后一个就是,有的时候我对于接收到的连接进行setsockopt的时候也会出现同样的报错,10038。所以想请问一下有没
有高手知道出现这种10038可能的原因。
我在网上看到有人说需要客户端在调用closesocket之前调用shutdown函数,我也加了,但是还是不能解决问题。
另外一个还有一种说法是监听线程的内存被污染了,但是如果是这样的话是不是那个socket值就应该会变了啊,我的监听线程是不会被工作线程干扰的,有人能提供一种证明我工作线程被污染或者保护监听线程的资源的方法也可以。

求高手救命啊
...全文
878 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
_小罗 2012-03-15
  • 打赏
  • 举报
回复
呵呵,一直没有结贴,问题现在虽然不存在了,但是我不太理解为什么重复非监听socket会导致监听线程出现那种错误

[Quote=引用 35 楼 chenjiawei007 的回复:]

以后做的仔细点呗,不要完全依赖于错误信息。呵呵 只是来看下结果。
[/Quote]
chenjiawei007 2012-03-05
  • 打赏
  • 举报
回复
以后做的仔细点呗,不要完全依赖于错误信息。呵呵 只是来看下结果。
zhanshen2891 2012-03-02
  • 打赏
  • 举报
回复
重复关闭套接字肯定没事!

除非是你把监听套接字关闭了,但是我觉得如果是把监听套接关闭了那应该也不是这个错误。
_小罗 2012-03-02
  • 打赏
  • 举报
回复
问题现在已经改好了,在我的库里面有closesocket,而且还没有判断,之前没有到那个库里面进行检查;
不知道原因是不是因为我重复closesocket了

[Quote=引用楼主 ecjtu_lyc 的回复:]
开发服务器程序,需要模拟几千个客户端,监听线程运行了一段时间之后,accept会失败,用wsagetlasterror获取的错误信息是10038,对非socket进行操作。
首先,网上说的可能是我什么地方调用了closesocket()函数,所以我在closesocket下面加了TRACE信息,打印了调用closesocket函数的所有的socket值,同时也TRACE了每次用于……
[/Quote]
wjb_yd 2012-02-29
  • 打赏
  • 举报
回复
推荐LZ试试ACE和boost.asio,只学你需要的部分,就行。
自己写的网络架子,难保不出问题,而且有的bug又极其难查。
wjb_yd 2012-02-29
  • 打赏
  • 举报
回复
是这样的,socket只代表一个句柄,也可以理解成一个指针。
虽然socket值没变,但真正指向的内容可能被破坏了,这种bug确实不好找。
LZ你可以试试,从最简单的通信逻辑开始,一点点的加其他逻辑,看看到底是添加哪块逻辑出得问题。
把应用层对数据的处理之类的先去掉,只排查网络通信的代码。
要是网络通信的架子没问题,就是逻辑有问题,有内存越界。
hdg3707 2012-02-29
  • 打赏
  • 举报
回复
是不是最大连接数溢出了,也就是如果最大连接数是有符号的16位数,那最大连接数只能是32767,否则就变成负数了
_小罗 2012-02-29
  • 打赏
  • 举报
回复
这跟数据类型有什么关系?[Quote=引用 30 楼 hdg3707 的回复:]

我说工作线程关闭,是说我服务启动的时候就不开工作线程,只接收连接,这种情况要连接数到32200以上才会出现异常,好像是65536/2
这怎么象是数据类型不对呢,就是有符号的16位类型和无符号的16位类型定义,看一下是不是有数据类型不合适
[/Quote]
hdg3707 2012-02-29
  • 打赏
  • 举报
回复
我说工作线程关闭,是说我服务启动的时候就不开工作线程,只接收连接,这种情况要连接数到32200以上才会出现异常,好像是65536/2
这怎么象是数据类型不对呢,就是有符号的16位类型和无符号的16位类型定义,看一下是不是有数据类型不合适
_小罗 2012-02-29
  • 打赏
  • 举报
回复
朋友你好,我刚才用一个终端模拟了一种情况,就是登陆上来之后马上断掉、重连,反复试,结果偶然发现一个问题,我有意在每次收到对方断开连接之后,服务器这边不进行closesocket,但是还是经常在accept的时候返回同一个socket,想问问这是什么原因或者会不会导致我的那个bug?

[Quote=引用 16 楼 chenjiawei007 的回复:]

客户端不需要进行shutdown的,只要你客户端closesocket,然后服务端recv检测这个socket返回-1,也进行closesocket,那这个握手后的连接就顺利结束了。

你在仔细的描述下你的现象,是不是 运行后一阵才出现的这样的线程?如果是,可能是你残存了很多连接数,也就是没有安全的关闭socket,句柄泄露了。

还有,你描述的一个现象说,你的工作线程关闭后,就没有这个……
[/Quote]
_小罗 2012-02-29
  • 打赏
  • 举报
回复
按你说的方法考虑下,那个ACE貌似很复杂
[Quote=引用 25 楼 wjb_yd 的回复:]
推荐LZ试试ACE和boost.asio,只学你需要的部分,就行。
自己写的网络架子,难保不出问题,而且有的bug又极其难查。
[/Quote]
_小罗 2012-02-29
  • 打赏
  • 举报
回复
今天偶然发现一个问题,因为自己简单的封装了一个SocketTcp的类,两个构造函数,一个有参,一个默认,有参构造函数中调用了bind和listen(之前是不调用的,后面加的)。后来改了之后没注意到这点,导致我主动连接的时候也对这个我主动连接的这个socket值进行了bind、listen、connect,现在问题还在,不知道这种问题会不会导致我的程序出现上述错误?

[Quote=引用 16 楼 chenjiawei007 的回复:]
客户端不需要进行shutdown的,只要你客户端closesocket,然后服务端recv检测这个socket返回-1,也进行closesocket,那这个握手后的连接就顺利结束了。

你在仔细的描述下你的现象,是不是 运行后一阵才出现的这样的线程?如果是,可能是你残存了很多连接数,也就是没有安全的关闭socket,句柄泄露了。

还有,你描述的一个现象说,你的工作线程关闭后,就没有这个问……
[/Quote]
hdg3707 2012-02-28
  • 打赏
  • 举报
回复
你可以根据IP地址判断是否有重复连接,也就是当收到一个请求时,先从客户端队列里看是否有这个IP地址,如果有,就把这个队列的相应的连接删除了,再重新建一个连接.没有就添加这个连接
也就是保证一个客户端只能有一个连接,不能有重复的连接.
gameslq 2012-02-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 ecjtu_lyc 的回复:]

能认真点回答么
[/Quote]
很可能监听的socket值被破坏了 贴代码 包含 accept函数之后的代码
luawkk 2012-02-28
  • 打赏
  • 举报
回复
socket 接口为初始化
WORD wVersionRequested; WSADATA wsaData;
int err = 0;

wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if( err != 0 )
{
return;
}

if( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup();
return;
}
_小罗 2012-02-28
  • 打赏
  • 举报
回复
这个我倒是没想过,但是可能用不了。因为我的服务器真实的应用场景中,终端是手机,有可能多个终端对应一个共有IP地址。其次我的模拟器是在一个电脑上开多个线程模拟终端,IP地址在测试时肯定是一样的

[Quote=引用 20 楼 hdg3707 的回复:]

你可以根据IP地址判断是否有重复连接,也就是当收到一个请求时,先从客户端队列里看是否有这个IP地址,如果有,就把这个队列的相应的连接删除了,再重新建一个连接.没有就添加这个连接
也就是保证一个客户端只能有一个连接,不能有重复的连接.
[/Quote]
_小罗 2012-02-28
  • 打赏
  • 举报
回复
明天借个U盘来贴代码,socket值被破坏是什么意思?
[Quote=引用 19 楼 gameslq 的回复:]

引用 2 楼 ecjtu_lyc 的回复:

能认真点回答么

很可能监听的socket值被破坏了 贴代码 包含 accept函数之后的代码
[/Quote]
_小罗 2012-02-28
  • 打赏
  • 举报
回复
1.我的确实是运行一段时间后才出现这个问题,但是时间很短,就收到了几千个客户端的连接而已,打印出来的连接成功次数才不到2000
2.我说工作线程关闭,是说我服务启动的时候就不开工作线程,只接收连接,这种情况要连接数到32200以上才会出现异常,好像是65536/2
3.我检查了我的工作线程没有调用到监听线程的那个类,当然有可能是内存污染,你说的低级错误是指哪一类?closesocket这种的还是哪类的?


[Quote=引用 16 楼 chenjiawei007 的回复:]

客户端不需要进行shutdown的,只要你客户端closesocket,然后服务端recv检测这个socket返回-1,也进行closesocket,那这个握手后的连接就顺利结束了。

你在仔细的描述下你的现象,是不是 运行后一阵才出现的这样的线程?如果是,可能是你残存了很多连接数,也就是没有安全的关闭socket,句柄泄露了。

还有,你描述的一个现象说,你的工作线程关闭后,就没有这个……
[/Quote]
chenjiawei007 2012-02-25
  • 打赏
  • 举报
回复
客户端不需要进行shutdown的,只要你客户端closesocket,然后服务端recv检测这个socket返回-1,也进行closesocket,那这个握手后的连接就顺利结束了。

你在仔细的描述下你的现象,是不是 运行后一阵才出现的这样的线程?如果是,可能是你残存了很多连接数,也就是没有安全的关闭socket,句柄泄露了。

还有,你描述的一个现象说,你的工作线程关闭后,就没有这个问题,那你的socket作用域上出问题的概率也很大。


做了很久的网络,在accept上出现问题,很少见,多检查下你的基本流程和对象作用域使用吧,基本可以断定是哪里犯了低级错误。
_小罗 2012-02-24
  • 打赏
  • 举报
回复
朋友,你好,之前回复了一次可能网速不行没刷出来
首先,我改过listen,改成2000还是不行,而且我出accept出错的时候连接成功数才1000多
还有,我的客户端程序都是先shutdown然后closesocket的

[Quote=引用 12 楼 chenjiawei007 的回复:]

你都是在自己一台电脑上测试的吗? 客户端的socket有没有关闭,不关闭会占连接数的。
[/Quote]
加载更多回复(13)

18,356

社区成员

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

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