我用 python 构建了客户端-服务器架构,不幸的是,最初的设计是对服务器的每个请求都由一个 TCP 连接表示,我必须以大组(20 000+)发送请求,有时会出现套接字错误#10055
.
我已经找到了如何在 python 中处理它:
>>> errno.errorcode[10055]
'WSAENOBUFS'
>>> errno.WSAENOBUFS
10055
并构建一个能够处理该错误并重新连接的代码(当然,几乎没有时间延迟,让服务器有时间做任何它必须做的事情):
class MyConnect:
# __init__ and send are not important here
def __enter__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Try several reconnects
for i in range(0,100):
try:
self.sock.connect((self.address, self.port))
break
except socket.error as e:
if e.errno == errno.WSAENOBUFS:
time.sleep(1)
else:
raise
return self
def __exit__(self, type, value, traceback):
self.sock.close()
# Pseudocode
for i in range(0,20000):
with MyConnect(ip,port) as c:
c.send(i)
我的问题是:
- 有什么“好的做法”可以做到这一点吗?
e.errno == errno.WSAENOBUFS
是多平台的吗?如果不是这样,如何使其成为多平台?
注意:我只在 Windows 上进行了测试,我也需要它在 Linux 上运行。
最佳答案
传出数据以及所有连接建立和终止数据包正在堵塞 TCP 堆栈。
如果您必须坚持此设计,则强制每个连接徘徊,直到其数据成功发送。也就是说,默认情况下,套接字上的 close()
会立即返回,并且进一步的传送尝试和连接拆除会“在后台”发生。您可以看到,在紧密循环中执行超过 20000 次以上很容易压垮操作系统网络堆栈。
以下内容将强制您的套接字 close()
挂起最多 10 秒以尝试传递数据:
import struct
s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 10))
请注意,这与 Python socket.sendall()
不同 - Python 只是将所有字节传递给内核。
希望这有帮助。
关于python - WinSock 错误 #10055,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13720262/