2017-10-13 87 views
0

予程序的服务器通过蟒发送DATAS到客户端,代码如下:在Linux和python上,什么使套接字超时?

server.py

import socket,time 
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #just for test 
sock.bind(("10.144.74.182",8080)) 
sock.listen(10) 
s,info=sock.accept() 
s.settimeout(60) 
while 1: 
    try: 
    t=time.time() 
    s.send("a"*4096) 
    print time.time()-t 
    except: 
    print time.time()-t 
    break 

client.py程序的

import socket,time 
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
sock.connect(("10.144.74.182",8080)) 
while 1: 
    time.sleep(5) 
    a=sock.recv(4096) 

部分输出:

enter image description here

但是,运行该程序时服务器超时。我的问题是为什么服务器超时如果网络是好的?客户端每5秒收到一次数据是否会导致服务器超时?

通过tcpdump,我发现当客户端的tcp recv窗口大小再次大于零时,客户端不会立即通知服务器,它会通知服务器,直到它的recv窗口大小超过某个特定值值,这可以从后续的PIC可以看出:

enter image description here

从PIC我们可以看到客户端noitfy服务器时,它的窗口大小为26368.Is有任何人知道的recv窗口的阈值大小,使客户端通知服务器?

+0

如果您想跟踪客户端,请勿使用'timeout'。另一点是“超时”仅适用于单个数据包(不是全部通信)。 – dsgdfg

+0

你说什么“不全面沟通”是什么意思? – Jay

+0

超时通常定义连接是否存在或系统最长的等待时间。此超时仅适用于单个数据包。它不用于文件或流控制,因为网络的状态和资源可访问性不稳定。出于这个原因,在套接字应用程序中使用附加的数据块和标志。如果要建立高速且充足的连接,超时功能将不起作用(忽略)。如果要建立关键数据连接,则状态和线路负载信息以特定时间间隔(<200毫秒)进行交换。 – dsgdfg

回答

0

您在这里观察到的“超时”是由于TCP套接字上发生的流量控制造成的。为了订购有保证的交付,TCP需要有一个接收者队列(在client.py上)和一个发送者队列(在server.py上)。如果客户端没有足够快地读取数据,首先接收者队列将被填满,然后发送者队列将被填满。此时,一旦两个队列都满了,服务器将在其呼叫s.send时阻塞,并且将保持阻塞状态,直到发送队列中的空间可用。

如果在Linux上,可以使用netstat命令查看套接字队列。

netstat -plan | grep ESTABLISHED | grep 8080 

例如,输出如下(我手动添加标题):

Proto Recv-Q Send-Q Local Address  Foreign Address State  PID/Program name 
tcp 795855  0 127.0.0.1:33652 127.0.0.1:8080 ESTABLISHED 1529/python  
tcp  0 2743089 127.0.0.1:8080 127.0.0.1:33652 ESTABLISHED 1525/python 

...在这里,可以看到非零数字为RECV-Q和Send-Q,这表明他们已经变得丰满,所以发件人直到接收器读取一些信息才能发送。