如果客户端停止,Python TCP Server将永远阻止发送到客户端(SIGSTOP)

时间:2019-03-11 21:17:44

标签: python linux sockets tcp

我在python中有一个非常简单的tcp服务器,其代码如下:

#!/usr/bin/env python                                                           

import socket

sock = socket.socket()

sock.connect(('',3912)) # in reality here I use the IP of the host where 
# I run the server since I launch the clients on a different host

while True:
    data = sock.recv(1000)
    print("received data: {} ".format(str(data)))

相应的客户代码为

./server.py

现在,如果我使用以下命令启动服务器

for i in `seq 1 10`; do ./client.py 2>/dev/null 1>/dev/null & done

和来自不同主机的10个客户端并行:

kill -SIGSTOP %1

我将send发送到第一个客户端,我希望服务器成功地继续尝试发送数据,因为它不知道客户端已停止。相反,服务器在尝试将数据发送到客户端1时会阻塞。如果客户端与服务器位于同一主机上,我可以理解行为:我们尝试写入数据,但是内核缓冲区已满,因此我们阻塞服务器,但客户端永远不会读取,因此永远不会释放缓冲区。但是,如果客户端在不同的计算机上,则服务器主机的内核缓冲区应仅暂时充满,然后内核应通过网卡发送数据并释放它们。那么,为什么我的服务器无法进行{{1}}调用?我尚未验证使用其他语言(例如C)时是否会看到相同的行为

1 个答案:

答案 0 :(得分:1)

这很奇怪,因为1000个字符对于TCP来说很小。我没有可用的Linux机器,但是在FreeBSD机器上,我可以通过TCP连接成功发送130000字节,在该TCP连接上,对等方在发送方阻塞之前已停止。在Windows上超过1000000。

但是,由于TCP是连接的协议,如果send调用由于内部TCP堆栈队列已满而无法将其数据排队,则会阻塞。