python - WinSock 错误 #10055

标签 python sockets error-handling python-3.x multiplatform

我用 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/

相关文章:

python - 如何加快读取多个文件并将数据放入数据框中?

sockets - 是否为RequestHandler.write提供了 Tornado 回调?

java - 带有 https 的 tomcat 在直接 TCP 连接时获得 CLOSE_WAIT

asp.net - Asp.net : unexpected Error-Handling - send mail and redirect to error.aspx?

python - 使用 Mechanize 和 python 的站点抓取下拉列表

python - 在 Django 中连接新的 celery 周期性任务

python - 如何将文件中的字符串更改为列表中的字符串

Android DatagramSocket错误信息: EADDRINUSE (Address already in use)

http - API 何时应抛出 4xx 状态代码(错误),何时抛出 5xx?

html - 浏览器呈现的代码而不是页面