【发布时间】: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 字符串。