如果服務端重啟,那麼客戶端的長連線會怎麼樣

2021-07-31 01:27:53 字數 1826 閱讀 9332

這裡記錄一次服務端重啟時,使用winshark的抓包過程;
場景是:sdk 建立對 服務端的長連線,客戶端連線策略是:

失活判斷: 一條連線 180s都沒有read到資料;

保活判斷: 每秒檢查一次,連續60次檢查都為空閒,那麼傳送一次keeplive包。

重連邏輯: 如果連線斷開,那麼會以2s 、 4s、  6s、  8s...這樣的遞增產生的時延,去重連,每次連線等待5s判斷連線超時而被認為連線失敗。

客戶端首先建立好對服務端的連線,然後關閉服務端,比如kill指令;

抓包分析:

1.由於是服務端被kill了,那麼client立即感知到連線被關閉,recv=0;

2.此時服務端正在**各種資源中,包括socket的資源,而客戶端2s後執行斷開重連的操作,居然連線成功了,並傳送訊息成功了。客戶端這條連線被認為是成功。

3.問題來了,大約過了一會,服務端會傳送乙個rst指令給客戶端,這個是通過抓包看得到的,然而使用ndk編碼實現的sdk,工作在android模擬器裡,居然沒有觸發select的 

讀事件;因為沒有被立即觸發,那麼客戶端就要等到乙個超時週期,直到判斷連線失活了,才closesocket。而在此期間,這條tcp連線都被認為是成功的。

問題是:為什麼既然對端發了乙個rst指令,而此端的select怎麼沒有檢查到readable事件呢;**如下:

void ctcpsocket::onselectevent()

debug_log("select");

int rc = select( m_hsocket+1, &readset, psendset , &exceptionalset, &tv ) ;

if (rc < 0)

if (1==m_inconnected)

int nerr = 0 ;

if ( fd_isset(m_hsocket,&exceptionalset) )

if ( fd_isset( m_hsocket, &readset ) )

if (/* nerr == 0 && psendset != null && */fd_isset( m_hsocket, &sendset) )

if ( nerr != 0 )

}

難道是我的這段基於select io 模式的**有問題?

然後我首先使用python寫了一段select的**,做相同的測試,發現很快就觸發了readevent;

然後我再把這段**在linux執行,也很快被對端的rst指令觸發了readevent事件;

相同**,在不同的平台的執行效果,可能就是不如預期的。除非把這一段**,在不同的平台都做了完整的測試。這段**被使用在客戶端裡,由此可以體會到客戶端開發的乙個難點,就是跨平台性。

我想不同平台對select的實現,是不是並不是完全一致的。比如我使用的android模擬器就是乙個linux核心的裁剪版本。這只能算乙個猜測,但是這足以說明寫乙個平台的**,是不能完全用在另乙個平台的經驗做主觀上完全沒問題的斷定的。實際,相同**的執行在不同的平台上執行結果,依舊充滿不確定性吧。

那麼針對我這個問題,保險起見,可以每次select之後,都可以直接觸發一次readevent;以保證客戶端**的可用性吧。

(ps: 這樣也解決不了問題:涉及測試時 read操作總是忙;最後我是怎麼解決的呢,把斷開連線重連的時延設定得更大了一旦,比如我我這次設定為6s,就避免了在服務端沒有完全釋放前,我又連線了上去;

但其實這個問題,我還是沒法解釋原因。

Python UDP客戶端 服務端

udpclient.py coding utf 8 from socket import servername 127.0.0.1 伺服器位址,本例中使用一台遠端主機 serverport 12000 伺服器指定的埠 clientsocket socket af inet,sock dgram 建立...

python udp客戶端,服務端

客戶端1 建立套接字 2 收發資料 3 關閉套接字 import socket 建立套接字 socket socket.socket socket.af inet,socket.sock dgram 傳送資料 傳送資料的型別必須是位元組型別 data 你猜 encode gbk addr 192.1...

udp服務端 客戶端

個數 2的16次方 埠是資料發出或接收的入口 埠的目的 通過埠號找到對應的程序,完成資料的通訊 著名埠0 1023 這是建立了乙個基於udp協議的服務端 import socket todo 1.0 建立了乙個套接字,用來連線客戶端,傳送與接收資料 udp server socket.socket ...