【问题标题】:How to resolve connection is reset?如何解决连接被重置?
【发布时间】:2021-03-10 02:39:48
【问题描述】:

我正在使用 python 套接字创建一个 p2p 网络,其中每个节点都有一个侦听线程和一个客户端线程,分别连接到其他节点并侦听其他节点连接。我在监听端创建了一个小缓冲协议,它将缓冲 msgs,直到它获得所有字节。

现在,我遇到的第一个问题是有时 socket.sendall() 不会发送所有字节,在这种情况下,我的侦听器(在其他节点上)无法知道发生了这种情况,因此它会尝试缓冲 msgs 直到它接收到 x amt 字节,然后在其上调用 json.loads() ,从而导致异常。为了解决这个问题,我决定在循环中使用 socket.send() 来确保所有字节都将按如下方式发送。

while total_sent < msg_len:
    sent = recipient_node['socket'].send(byte_msg[total_sent:])
    if sent == 0: # disconnected?
        pass
    total_sent += sent

我现在遇到一个新错误,即“对等方重置连接”,堆栈跟踪显示该错误发生在 socket.send() 上。我知道这是由于一些 GIL 问题,并且在发送之前插入 time.sleep(.0001) 或其他东西可以解决这个问题(有点),但当然会减慢 p2p 网络。

然后我的问题是,有没有一种方法可以确保使用 sendall() 传递所有字节,或者是否有更好的方法使用 send() 和 time.sleep()。我对任何一个都持开放态度。

【问题讨论】:

  • 你在问哪个问题? - how to ensure all bytes are sent/received?What does connection reset by peer mean and how to fix it?is there a better solution to my working solution?
  • @wwii 很抱歉造成混乱。所以此时我知道上面的代码 sn-p 将在多次迭代中发送所有字节。我现在正在处理连接被重置错误。正如我在上面的编辑中发布的那样,我在某处看到在发送之前放置一个 time.sleep 可以解决这个问题,这与 GIL 有关吗?我在 vms 上对此进行了测试,它似乎解决了这个问题,但是现在当然 1ms 的延迟在发送中非常明显。我想知道是否有更好的解决方案。
  • 明确地说,我现在通过在循环中使用发送来重置此连接。在我使用 sendall 之前,但决定使用 send 因为如果 sendall 不发送所有字节(有时会发生这种情况),那么每个节点上的侦听器就无法知道如何解析垃圾数据或清理它确保它不会尝试解析不完整的 json 字符串。

标签: python sockets tcp


【解决方案1】:

Welp,我想通了。我实际上弄清楚了我遇到的原始问题。由于我使用 select 作为我的非阻塞侦听器,它基本上是一段专用的代码来处理每个套接字连接,因此 recvs 不需要来自一个节点。我现在使用缓冲区映射代替缓冲区字符串,将每个客户端套接字映射到其自己的缓冲区字符串,这样它就不会混合来自不同套接字的消息。我不敢相信我直到现在才意识到这种情况正在发生。仍然很奇怪,即使缓冲区会混合在一起,很多时候它仍然可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多