本文介绍了重新使用套接字时套接字使用错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我在c ++中编写一个XMLRPC客户端,目的是与python XMLRPC服务器通信。不幸的是,目前python XMLRPC服务器只能在连接上发送一个请求,然后关闭,我发现这是由于mhawke对我的响应有关相关主题的上一个查询 因此,我必须创建一个新的套接字连接到我的python服务器每次我想做一个XMLRPC请求。这意味着创建和删除了很多套接字。一切工作正常,直到我接近〜4000请求。此时,我会收到套接字错误 10048,Socket正在使用。 我试着睡觉的线程让winsock修复它的文件描述符,一个工具当我的一个python客户端有相同的问题,没有效果。 我试过下面的代码: int err = setsockopt(s_,SOL_SOCKET,SO_REUSEADDR, ,sizeof(BOOL)); 未成功。 m使用winsock 2.0,所以WSADATA :: iMaxSockets不应该发挥,和任何一种方式,我检查和其设置为0(我假设意味着无穷大) 4000个请求看起来不像是在应用程序运行期间发出的异常数量的请求。在服务器持续关闭和重新打开时,是否有某种方法在客户端使用SO_KEEPALIVE? 我完全缺少某些东西?问题是由于挂起在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() printLowest port:,sockets [0] [1],Highest port: 1] #在Windows上你应该看到这样的... 3960 最低端口:1025最高端口:5000 如果您尝试再次运行此immeditaely,它应该会很快失败,因为所有动态端口都处于TIME_WAIT状态。 有几种方法: 管理您自己的端口分配和使用 bind()将客户端套接字显式绑定到特定的端口,每次创建一个套接字时都会递增。你仍然有来处理端口是已经在使用的情况,但是你不会被限制为动态端口。例如 port = 5000 while True:s = socket.socket() .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) 我不知道这将有助于您的特定应用程序,然而,有可能通过发送多个XMLRPC请求,使用 multicall 方法。基本上这允许你累积几个请求,然后一次发送他们。你不会得到任何响应,直到你实际发送累积的请求,所以你可以本质上认为这是批处理处理 - 这适合与您的应用程序设计? I am writing an XMLRPC client in c++ that is intended to talk to a python XMLRPC server.Unfortunately, at this time, the python XMLRPC server is only capable of fielding one request on a connection, then it shuts down, I discovered this thanks to mhawke's response to my previous query about a related subjectBecause of this, I have to create a new socket connection to my python server every time I want to make an XMLRPC request. This means the creation and deletion of a lot of sockets. Everything works fine, until I approach ~4000 requests. At this point I get socket error 10048, Socket in use.I've tried sleeping the thread to let winsock fix its file descriptors, a trick that worked when a python client of mine had an identical issue, to no avail.I've tried the followingint err = setsockopt(s_,SOL_SOCKET,SO_REUSEADDR,(char*)TRUE,sizeof(BOOL));with no success.I'm using winsock 2.0, so WSADATA::iMaxSockets shouldn't come into play, and either way, I checked and its set to 0 (I assume that means infinity)4000 requests doesn't seem like an outlandish number of requests to make during the run of an application. Is there some way to use SO_KEEPALIVE on the client side while the server continually closes and reopens?Am I totally missing something? 解决方案 The problem is being caused by sockets hanging around in the TIME_WAIT state which is entered once you close the client's socket. By default the socket will remain in this state for 4 minutes before it is available for reuse. Your client (possibly helped by other processes) is consuming them all within a 4 minute period. See this answer for a good explanation and a possible non-code solution.Windows dynamically allocates port numbers in the range 1024-5000 (3977 ports) when you do not explicitly bind the socket address. This Python code demonstrates the problem:import socketsockets = []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...3960Lowest port: 1025 Highest port: 5000If you try to run this immeditaely again, it should fail very quickly since all dynamic ports are in the TIME_WAIT state.There are a few ways around this:Manage your own port assignments anduse bind() to explicitly bind yourclient socket to a specific portthat you increment each time yourcreate a socket. You'll still haveto handle the case where a port isalready in use, but you will not belimited to dynamic ports. e.g.port = 5000while True: s = socket.socket() s.bind(('your_host', port)) s.connect(('some_host', 80)) s.close() port += 1Fiddle with the SO_LINGER socketoption. I have found that thissometimes works in Windows (althoughnot exactly sure why):s.setsockopt(socket.SOL_SOCKET,socket.SO_LINGER, 1)I don't know if this will help inyour particular application,however, it is possible to sendmultiple XMLRPC requests over thesame connection using themulticall method. Basicallythis allows you to accumulateseveral requests and then send themall at once. You will not get anyresponses until you actually sendthe accumulated requests, so you canessentially think of this as batchprocessing - does this fit in withyour application design? 这篇关于重新使用套接字时套接字使用错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!