日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java检测tcp存活_keep-alive 和 TCP存活检测

發布時間:2025/4/17 编程问答 59 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java检测tcp存活_keep-alive 和 TCP存活检测 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是keep-alive?

顧名思義即可,注意它只適用于TCP連接。系統會替你維護一個timer,時間到了,就會向remote peer發送一個probe package,當然里面是沒有數據的,對方就會返回一個應答,這時你就知道這個通道保持正常。

有什么用呢?

考慮下面這個場景,端點A和端B開始連接,三次握手,建立好了一個穩定的雙向通道。然后雙方發送完初始的數據后,進入等待狀態。這時候,拔掉B的電源插頭,B死掉了,它不可能有任何機會向A發送FIN包,或是其他數據來說明自己掛掉,需要終止連接。因此A只是簡單的繼續等待。然后重啟機器和應用程序,B又恢復原始的狀態,可是原本的連接已經沒有了,之后就可能有三種情況,雙方繼續傻等,或是B向A發起新的請求,最可能的還是A向B發送新的數據,這時B因為原有的socket已經死了,就返回一個RST,A關閉連接。看下面的圖: _____ _____

| | | |

| A | | B |

|_____| |_____|

^ ^

|--->--->--->-------------- SYN -------------->--->--->---|

|---

|--->--->--->-------------- ACK -------------->--->--->---|

| |

| system crash ---> X

|

| system restart ---> ^

| |

|--->--->--->-------------- PSH -------------->--->--->---|

|---

| |

上面的場景就提出了一個需求,作為服務器端,可不能老是傻等是不是,當然timeout也是一個方案了,不過如果是IM這種類型的服務器,總不能用戶一段時間沒反應,就把它給踢了吧。

keep-alive還有另外一個有點trick的作用,考慮另外一個場景,一般的終端總是位于防火墻或是NAT后面,而這些設備限制于硬件,不可能處理任意數量的連接,在內部隊列滿的時候,總是要把最不活躍的連接給砍了的。這個時候keep-alive就可以發揮最用了。看下面的圖:

_____ _____ _____

| | | | | |

| A | | NAT | | B |

|_____| |_____| |_____|

^ ^ ^

|--->--->--->---|----------- SYN ------------->--->--->---|

|---

|--->--->--->---|----------- ACK ------------->--->--->---|

| | |

| |

| | |

|--->- PSH ->---|

| | |

程序上如何使用呢?

無論是windows還是linux都實現了這個功能,你只需要設置socket的屬性即可,當然你也可自己實現這個功能,也就是定期發送心跳包.

先說linux平臺:

一般的實現如下,也就是說每過7200s空閑(兩個小時),就會發送一個探測包,如果沒有應答,就隔75s,再次發送,連續9次沒有反應,就判定該連接死了。

# cat /proc/sys/net/ipv4/tcp_keepalive_time

7200

# cat /proc/sys/net/ipv4/tcp_keepalive_intvl

75

# cat /proc/sys/net/ipv4/tcp_keepalive_probes

9

如何改呢,可以用直接該系統默認值,則全局都會有效,這似乎不大合適。 如果是程序中,則只要設置socket的屬性就行了,調用setsockopt,首先打開keep-alive功能:

int optval = 1;

socklen_t optlen = sizeof(optval);

if(setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {

perror("setsockopt()");

close(s);

exit(EXIT_FAILURE);

}

然后設定要改的值,像這樣:

setsockopt (fd, SOL_TCP, TCP_KEEPIDLE, &newValue, optlen);

TCP_KEEPCNT: 代表 tcp_keepalive_probes

TCP_KEEPIDLE: 代表 tcp_keepalive_time

TCP_KEEPINTVL: 代表 tcp_keepalive_intvl

windows平臺上也是差不多:

windows中也是可以做出系統級別的調整的, 對于Win2K/XP/2003,可以從下面的注冊表項找到影響整個系統所有連接的參數:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]

“KeepAliveTime”=dword:006ddd00

“KeepAliveInterval”=dword:000003e8

“MaxDataRetries”=”5″

在程序中來設定的話,首先先打開keep-alive,跟在linux中是一樣的,

BOOL bKeepAlive = TRUE;

int nRet = ::setsockopt(socket_handle, SOL_SOCKET, SO_KEEPALIVE, (char*)&bKeepAlive, sizeof(bKeepAlive));

然后調整具體的參數,需要調用WSAIoctl

tcp_keepalive alive_in = {0};

tcp_keepalive alive_out = {0};

alive_in.keepalivetime = 5000;

alive_in.keepaliveinterval = 1000;

alive_in.onoff = TRUE;

unsigned long ulBytesReturn = 0;

nRet = WSAIoctl(socket_handle, SIO_KEEPALIVE_VALS, &alive_in, sizeof(alive_in), &alive_out, sizeof(alive_out), &ulBytesReturn, NULL, NULL);

開啟Keepalive選項之后,對于使用IOCP模型的服務器端程序來說,一旦檢測到連接斷開,GetQueuedCompletionStatus函數將立即返回FALSE,使得服務器端能及時清除該連接、釋放該連接相關的資源。對于使用 select模型的客戶端來說,連接斷開被探測到時,以recv目的阻塞在socket上的select方法將立即返回SOCKET_ERROR,從而得知連接已失效,客戶端程序便有機會及時執行清除工作、提醒用戶或重新連接。

總結

以上是生活随笔為你收集整理的java检测tcp存活_keep-alive 和 TCP存活检测的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。