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
然后一切都正常了,但现在第三碎片被丢弃。
这毫无意义。有什么解释吗?
特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报