数据结束时停止 s.recv

Stop s.recv when data ends

提问人:E.V.A. 提问时间:11/9/2023 更新时间:11/9/2023 访问量:35

问:

我有一个 python 脚本,它本质上是将日志从服务器发送到客户端,但是我不知道日志会有多长。

一旦客户端收到日志,我就必须将它们写入文件,

客户端代码如下所示:

    with open('raw.txt', 'wb') as f:
    while True:
        logsreturned = s.recv(512)
        print(logsreturned)
        if logsreturned == '':
            break
        if not logsreturned:
            break
        f.write(logsreturned)
        logsreturned = ''

然而,最终发生的事情是日志的最后一部分没有被写入文件,客户端最终挂起,我不知道为什么

我已经尝试了上述两个 break 子句,看看我是否可以让客户端在完成后退出 while 循环,但是它仍然没有将最后一个小于 512 字节的字节写入文件

Python 套接字 文件处理

评论

2赞 President James K. Polk 11/9/2023
您的代码格式不正确。如果对等方从未关闭连接,客户端将“挂起”。你需要一个更好的协议。日志消息是否以某种方式格式化,例如始终始终以换行符 () 字符结尾?\n
1赞 CtrlZ 11/9/2023
客户端可以关闭连接,也可以发送约定俗成的序列(或单个字符,如 EOT)来指示没有更多数据可跟踪
0赞 user207421 11/9/2023
单个字符是不必要的,并且需要一个完整的转义协议,以防它出现在消息中。

答:

1赞 Steffen Ullrich 11/9/2023 #1

recv每当数据可用时都会返回,无论这些数据是否是最后的数据。TCP中没有“最后数据”的概念(假设这是你使用的),只有连接关闭/关闭的概念。并且会在连接关闭/关闭时返回。除此之外,将阻止,直到新数据进入或连接关闭/关闭。recv''recv

但这应该无关紧要,因为每当有新数据传入时,您都会写入文件。相反,可能的问题是,在关闭文件之前,这些数据仍处于缓冲状态。若要防止出现这种情况,请在每次写入后显式刷新数据,或禁用缓冲,如所述

with open('raw.txt', 'wb', buffering = 0) as f:

评论

0赞 E.V.A. 11/9/2023
非常感谢,客户端现在将所有数据写入文件,但它仍然挂起并且不会从 while 循环中断
3赞 Steffen Ullrich 11/9/2023
@E.V.A.:正如我所说,当服务器关闭或关闭连接时,客户端会返回 in。如果服务器只是在保持连接打开的同时停止发送,则无法将其与数据的临时暂停或结束区分开来。请注意,我仍然在这里假设 TCP,即使这从您的代码中不清楚。对于UDP,情况就不同了:没有连接关闭,但也没有“没有更多数据”——必须改用超时,并假设如果一段时间没有数据到达,服务器就完成了。''recv