我在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)时是否会看到相同的行为
答案 0 :(得分:1)
这很奇怪,因为1000个字符对于TCP来说很小。我没有可用的Linux机器,但是在FreeBSD机器上,我可以通过TCP连接成功发送130000字节,在该TCP连接上,对等方在发送方阻塞之前已停止。在Windows上超过1000000。
但是,由于TCP是连接的协议,如果send
调用由于内部TCP堆栈队列已满而无法将其数据排队,则会阻塞。