返回

python-Linux 上 TCP 套接字的 recv() 水印的行为不一致

发布时间:2022-05-07 03:32:51 238
# node.js

我在钻研套接字可调性,遇到了SO_RCVLOWAT选项,所以我创建了一个测试用例,以确定水印是否消除了我以前在开发服务器时遇到的一个特定问题(即过早的数据截断:)

def run_server(host: str, port: int, low_watermark: int):
    sk_server = socket.socket()
    sk_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    sk_server.setsockopt(
        socket.SOL_SOCKET, socket.SO_RCVLOWAT, low_watermark
    )
    sk_server.bind((host, port))
    sk_server.listen(1)
    cl_sockfd, cl_addr = sk_server.accept()
    print(f"connected to client, receiving at least {low_watermark}"
           " bytes of data")
    assert len(cl_sockfd.recv(low_watermark)) == low_watermark
    # *** never reached
    print("all good!")


if __name__ == "__main__":
    host, port = "localhost", 6969
    watermark = 100
    thd_server = threading.Thread(
        target=run_server,
        args=(host, port, watermark)
    )
    thd_server.start()
    time.sleep(0.5)

    client = socket.socket()
    client.connect((host, port))

    fragment_1 = b"a" * (n := watermark // 2)
    fragment_2 = b"a" * (watermark - n)

    print("sending first fragment, and waiting 1 second")
    print("sent", client.send(fragment_1), "bytes")
    time.sleep(1)

    print("sending second fragment")
    print("sent", client.send(fragment_2), "bytes")
    print("done. waiting for server thread to finish")

    thd_server.join()

简言之,客户机准确地发送watermark将字节发送到配置为至少接收watermark然而,主要的问题是服务器挂起在cl_sockfd.recv(low_watermark).

作为一种精神检查,我发送了一个大小的片段watermark,当然,这和预期的一样有效,下面的任何一个片段watermark被拒绝。但是,我有一个奇怪的发现,只有使用两个片段,服务器才能接受send()当第二个碎片的大小watermark,在这种情况下,两个碎片按预期结合,但剩余的长度watermark被丢弃,但是如果我改为发送三个片段,前两个片段加在一起构成长度watermark,但第三个碎片的大小watermark // 2然后一切都正常了,但现在第三碎片被丢弃。

这毫无意义。有什么解释吗?

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像