首先,我已经阅读了相当多的时间,包括该站点上的许多线程,但是我仍然需要对 Python 中的套接字、TCP 和网络进行一些澄清,因为我觉得我不完全理解什么是发生在我的程序中。
我正在使用 TCP (SOCK_STREAM) 通过 Unix 域套接字 (AF_UNIX) 从服务器向客户端发送数据。
在服务器端,一个进程不断地将项目放入 Queue.Queue 中,另一个进程通过运行将项目发送到客户端
while True:
conn.sendall(queue.get())
在客户端,通过运行读取数据
while True:
conn.recv(1024)
# time.sleep(10)
现在,我通过在每次调用 recv() 后让客户端进程休眠来模拟一个慢速客户端。我期望的是服务器端的队列已满,因为 send() 应该阻塞,因为客户端无法足够快地读取数据。
我监控发送到客户端的项目数量以及队列大小。我注意到有几十条消息(大致取决于消息的大小,但消息大小略有不同可能表现相同)被发送到客户端(由于 time.seep() 的原因,客户端延迟接收这些消息) 在队列开始填满之前。
这里发生了什么?为什么 send() 没有立即阻塞?
我怀疑涉及某种网络或文件缓冲区,它们将发送的项目排队并在我实现的队列之前填满。
最佳答案
在系统的不同位置,发送方和接收方都有许多缓冲区。在所有这些缓冲区都填满之前,您对发送函数的调用不会阻塞。当接收方耗尽一些缓冲区时,数据将再次流动并最终解除对发送调用的阻塞。
通常在发送方中有一个缓冲区,用于保存等待传输的数据,一个“正在运行”的缓冲区允许在必须等待接收方确认之前发送一定数量的字节,最后接收缓冲区保存已确认但尚未交付给接收应用程序的数据。
否则,前进的进展将极其有限。发送方将一直等待发送,直到接收方调用 receive。然后,无论哪个先完成,都必须等待另一个。即使发送方先完成,在接收方处理完前一个数据 block 之前,它也根本无法进行任何前进。对于大多数应用程序来说,这都不是最佳选择。
关于Python 套接字 : Question regarding Network Buffers when using send() and recv(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57342914/