当前位置:  开发笔记 > 编程语言 > 正文

重新使用套接字时出现套接字错误

如何解决《重新使用套接字时出现套接字错误》经验,为你挑选了1个好方法。

我正在用c ++编写一个XMLRPC客户端,用于与python XMLRPC服务器通信.

不幸的是,此时,python XMLRPC服务器只能在连接上发出一个请求,然后关闭,我发现这要归功于mhawke对我之前关于相关主题的查询的回复

因此,每次我想要发出XMLRPC请求时,我都必须创建一个到我的python服务器的新套接字连接.这意味着创建和删除许多套接字.一切正常,直到我接近~4000个请求.此时我收到套接字错误10048,正在使用套接字.

我试过睡觉线程让winsock修复它的文件描述符,这个技巧在我的python客户端有相同的问题时起作用,但无济于事.我尝试了以下内容

int err = setsockopt(s_,SOL_SOCKET,SO_REUSEADDR,(char*)TRUE,sizeof(BOOL));

没有成功.

我正在使用winsock 2.0,所以WSADATA :: iMaxSockets不应该发挥作用,无论哪种方式,我检查并将其设置为0(我认为这意味着无穷大)

4000个请求似乎不是在应用程序运行期间发出的异常数量的请求.当服务器不断关闭并重新打开时,有没有办法在客户端使用SO_KEEPALIVE?

我完全错过了什么吗?



1> mhawke..:

问题是由于在关闭客户端套接字时输入的TIME_WAIT状态中挂起的套接字引起的.默认情况下,套接字将保持此状态4分钟,然后才能重用.您的客户(可能由其他流程帮助)在4分钟内消耗它们.请参阅此答案以获得良好的解释和可能的非代码解决方案.

当您没有显式绑定套接字地址时,Windows会动态分配1024-5000(3977端口)范围内的端口号.这个Python代码演示了这个问题:

import socket
sockets = []
while True:
    s = socket.socket()
    s.connect(('some_host', 80))
    sockets.append(s.getsockname())
    s.close()

print len(sockets)    
sockets.sort()
print "Lowest port: ", sockets[0][1], " Highest port: ", sockets[-1][1]
# on Windows you should see something like this...
3960
Lowest port: 1025  Highest port: 5000

如果您尝试再次运行此命令,它应该很快失败,因为所有动态端口都处于TIME_WAIT状态.

有几种方法可以解决这个问题:

    管理您自己的端口分配,并用于bind()将客户端套接字显式绑定到每次创建套接字时递增的特定端口.您仍然需要处理端口已在使用的情况,但您不会局限于动态端口.例如

    port = 5000
    while True:
        s = socket.socket()
        s.bind(('your_host', port))
        s.connect(('some_host', 80))
        s.close()
        port += 1
    

    摆弄SO_LINGER套接字选项.我发现这有时适用于Windows(虽然不完全确定原因): s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, 1)

    我不知道这对您的特定应用程序是否有帮助,但是,可以使用multicall方法通过同一连接发送多个XMLRPC请求 .基本上,这允许您累积多个请求,然后一次发送所有请求.在实际发送累积请求之前,您不会得到任何响应,因此您基本上可以将其视为批处理 - 这是否适合您的应用程序设计?

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有