Python 套接字:关于使用 send() 和 recv() 时的网络缓冲区的问题

Python Sockets: Question regarding Network Buffers when using send() and recv()

首先,我已经阅读了相当多的时间,包括该站点上的许多线程,但是我仍然需要对 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() 没有立即阻塞?

我怀疑涉及某种网络或文件缓冲区,它将发送的项目排队并在我实现的队列之前填满。

在系统的不同位置,发送方和接收方都有许多缓冲区。在所有这些缓冲区都填满之前,您对发送函数的调用不会阻塞。当接收方耗尽一些缓冲区时,数据将再次流动并最终解除对发送调用的阻塞。

通常在发送方中有一个缓冲区,用于保存等待传输的数据,一个缓冲区 "in flight" 允许在必须等待接收方确认之前发送一定数量的字节,最后接收缓冲区保存已确认但尚未传送到接收应用程序的数据。

否则,前进的步伐将极其有限。发送方将一直等待发送,直到接收方调用 receive。然后,无论哪个先完成,都必须等待另一个。即使发送方先完成,在接收方处理完前一个数据块之前,它也根本无法进行任何前进。对于大多数应用程序来说,这将是次优的。