2017-10-13 85 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,這表明他們已經變得豐滿,所以發件人直到接收器讀取一些信息才能發送。