繁体   English   中英

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

[英]Python TCP Server blocks forever in send to client if client is stopped (SIGSTOP)

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

#!/usr/bin/env python                                                           

import socket

sock = socket.socket()

sock.bind(('',3912))
sock.listen(100)

num_cons = 10
cons = []
for i in range(num_cons):
    con, addr = sock.accept()
    cons.append(con)

while True:
    for con in cons:
        msg = "a"* 1000
        num_sent = con.send(msg.encode())
        print("sent: {} bytes of msg:{}".format(str(num_sent), msg))

相应的客户端代码是

#!/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

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

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

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

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

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

问题的要点似乎是要创建SOCK_STREAM套接字(即TCP),然后突然终止客户端。 如Python Socket Programming HOWTO中所讨论的,在这种情况下预期会挂起。

TCP是可靠的协议,这意味着必须对每个传输的数据包进行确认。 如果接收方已死,则发送方将阻止等待该确认。 尝试设置超时,看看您的send是否在预期时间之后引发了socket.timeout

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM