當前位置:首頁 » 雲伺服器 » javatcp如何判斷伺服器斷開鏈接

javatcp如何判斷伺服器斷開鏈接

發布時間: 2023-01-29 09:18:51

❶ tcp連接的斷開

TCP的斷開就是經過四次揮手: 這是正常的情況,客戶端主動tcp連接斷開的過程。客戶端先是發送一個FIN為一的報文,然後進入FIN_WAIT_1的狀態。 伺服器收到FIN報文後,發送一個ACK報文,然後進入CLOSED_WAIT狀態。 客戶端收到伺服器的ACK報文進入FIN_WAIT_2狀態。 等到伺服器覺得他數據處理好了,可以關閉的時候,會發送一個FIN報文,然後進入LAST_ACK。等待最後一個應答。 讓客戶端收到伺服器FIN報文,就進入TIME_WAIT狀態了,隨後發送最後一個ACK報文,然後close。 客戶端再等待2msl後也自己主動關閉。而只有主動關閉的情況下,才會有TIME_WAIT。 那麼為什麼四次揮手需要四次呢? 三次握手其實就是在第二次把ACK和SYN兩個報文合並成一個發,但是斷開的過程可能還有一方需要處理下數據,需要延長點時間,等處理好再發FIN,所以就比三次握手多了一次。 這里還有一個問題,為什麼需要TIME_WAIT,然後到close需要2msl的時間呢? 先說下什麼是MSL,也就是報文的最長生存時間,超過這個時間的報文就要被丟棄掉。tcp是基於ip的,ip上有個生存時間TTL,是ip報文可以經過的最大路由數量,每經過一個路由就減1,減到0,ip報文就丟棄掉,然後通過ICMP通知源主機,我們的ping也算是經過這個。當然msl和ttl還是有區別的,msl是時間,ttl是路由數量,msl也是大於等於ttl的。在linux中,2msl默認是60秒。 前文也說了,只有主動發起斷開連接的進程才會有time wait狀態。time wait+2msl有兩個原因: 1.防止舊連接的數據包 像這個seq 301的包,如果因為網路的原因被延遲了,而沒有time wait或者很短,那麼連接斷開後,又建立新的連接,這個時候這個包到了,可能就導致數據紊亂了。而2msl可以保證兩個方向的包在斷開前丟棄掉。 2.保證正確的斷開連接 2msl的時間也是保證第四個報文的ack可以被被動關閉方接收到。 如圖,假設time wait比較短或者沒有,當最後的ack報文丟失的時候。客戶端已經close了,而伺服器一直處於last ack的狀態。這樣連接就不能正常斷開了。而如果有time wait +2msl這個情況就可以避免。假設伺服器沒有收到最後一個ack報文,伺服器會重發FIN等待客戶端的ack。 這樣就可以保證不會出現一端斷開,另外一端沒有斷開的情況了。 有時候我們在伺服器上會看到很多time wait。time wait一般就是伺服器主動發起的斷開請求才會產生的狀態。所以time wait過多,第一個是系統資源會大量消耗,還有是埠如果占的太多,會導致沒辦法創建新連接。這個時候可以把linux的net.ipv4.tcp_tw_reuse開啟,置為1,可以復用time wait超過1秒的連接。 這邊再說說tcp的保活機制。也就是怎麼長期維持客戶端和服務端的連接。 在一個時間段內,如果沒有連接等相關活動,tcp的保活機制會定期發探測報文,如果連續幾個探測報文就沒有回應,就將錯誤信息報告給系統,系統通知上層應用。 在 Linux 內核可以有對應的參數可以設置保活時間、保活探測的次數、保活探測的時間間隔,以下都為 默認值: tcp_keepalive_time=7200:表示保活時間是 7200 秒(2⼩時),也就 2 小時內如果沒有任何連接 相關的活動,則會啟動保活機制 tcp_keepalive_intvl=75:表示每次檢測間隔 75 秒; tcp_keepalive_probes=9:表示檢測 9 次無響應,認為對⽅方是不不可達的,從⽽而中斷本次的連接。 也就是說在 Linux 系統中,最少需要經過 2 小時 11 分 15 秒才可以發現一個「死亡」連接。 當然這個時間也可以自己配置。

❷ 客戶端怎麼判斷Socket連接已與伺服器斷開

法一:

當recv()返回值小於等於0時,socket連接斷開。但是還需要判斷 errno是否等於 EINTR,如果errno == EINTR 則說明recv函數是由於程序接收到信號後返回的,socket連接還是正常的,不應close掉socket連接。

法二:

struct tcp_info info;
int len=sizeof(info);
getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
if((info.tcpi_state==TCP_ESTABLISHED)) 則說明未斷開 else 斷開

法三:

若使用了select等系統函數,若遠端斷開,則select返回1,recv返回0則斷開。其他注意事項同法一。

法四:

int keepAlive = 1; // 開啟keepalive屬性
int keepIdle = 60; // 如該連接在60秒內沒有任何數據往來,則進行探測
int keepInterval = 5; // 探測時發包的時間間隔為5 秒
int keepCount = 3; // 探測嘗試的次數.如果第1次探測包就收到響應了,則後2次的不再發.

setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

設置後,若斷開,則在使用該socket讀寫時立即失敗,並返回ETIMEDOUT錯誤

法五:

自己實現一個心跳檢測,一定時間內未收到自定義的心跳包則標記為已斷開。

java網路編程中,對於客戶端和伺服器的tcp連接,如果客戶端異常斷開連接,伺服器端如何獲知,有什麼方法

這個得用java心跳處理機制。就是客戶端每隔一段時間向伺服器發送指定信息,如果伺服器沒有收到客服端發來的信息,這時伺服器和客服端連接就已經斷開。具體的心跳實現網路上很多。

❹ TCP協議中客戶端closescoket後,伺服器怎麼知道此用戶已經斷開

你可以根據伺服器收到的數據的長度來判斷,如果伺服器收到的數據長度是0,那麼意味著你的客戶端程序已經斷開了連接。從TCP/IP協議棧的角度來說,就是客戶端程序關閉了自己寫的這一半連接,向伺服器發出了一個FIN。這涉及到TCP的狀態遷移,關於這方面的知識,建議你看一下Richard
Stevens先生的《TCP/IP
詳解》卷一和《Unix網路編程》卷一,上面有詳細的解釋。
關於你的第二個問題,建議你仔細看一下自己的伺服器程序代碼。伺服器程序首先要建立一個監聽socket,當有客戶端連接上來時,伺服器會在一個新socket上接受客戶端連接。所以並不存在「亂」的問題。關於這個問題同樣推薦你看上面的兩本關於網路編程的經典著作。

❺ java socket怎麼判斷斷開連接

一個方法sendUrgentData,查看文檔後得知它會往輸出流發送一個位元組的數據,只要對方Socket的SO_OOBINLINE屬性沒有打開,就會自動舍棄這個位元組,而SO_OOBINLINE屬性默認情況下就是關閉的
下面一段代碼就可以判斷遠端是否斷開了連接:
try{
socket.sendUrgentData(0xFF);
}catch(Exception ex){
reconnect();
}

熱點內容
抗生素資料庫 發布:2024-04-19 22:13:03 瀏覽:495
晚晚教編程 發布:2024-04-19 21:56:23 瀏覽:712
安卓換蘋果語音留言怎麼看 發布:2024-04-19 21:56:21 瀏覽:627
解壓神經 發布:2024-04-19 21:47:03 瀏覽:894
c語言字元轉義字元 發布:2024-04-19 21:43:51 瀏覽:727
mysql存儲過程語法 發布:2024-04-19 21:00:04 瀏覽:245
修復損壞的壓縮文件 發布:2024-04-19 20:53:32 瀏覽:423
編程發型 發布:2024-04-19 20:53:28 瀏覽:500
去除空格sql 發布:2024-04-19 20:43:30 瀏覽:785
linuxcp覆蓋 發布:2024-04-19 20:43:30 瀏覽:189