tcp是面向連線的,在實際應用中通常都需要檢測連線是否還可用.如果不可用,可分為:
a. 連線的對端正常關閉.
b. 連線的對端非正常關閉,這包括對端裝置掉電,程式崩潰,網路被中斷等.這種情況是不能也無法通知對端的,所以連線會一直存在,浪費國家的資源.
tcp協議棧有個keepalive的屬性,可以主動探測socket是否可用,不過這個屬性的預設值很大.
linux方法:
全域性設定可更改/etc/sysctl.conf,加上:
net.ipv4.tcp_keepalive_intvl = 20
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 60
在程式中設定如下:
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));
windows方法:
//定義結構及巨集
struct tcp_keepalive ;
#define sio_keepalive_vals _wsaiow(ioc_vendor,4)
//keepalive實現
tcp_keepalive inkeepalive = ; //輸入引數
unsigned long ulinlen = sizeof(tcp_keepalive);
tcp_keepalive outkeepalive = ; //輸出引數
unsigned long uloutlen = sizeof(tcp_keepalive);
unsigned long ulbytesreturn = 0;
//設定socket的keep alive為5秒,並且傳送次數為3次
inkeepalive.onoff = 1;
inkeepalive.keepaliveinterval = 5000; //兩次keepalive探測間的時間間隔
inkeepalive.keepalivetime = 5000; //開始首次keepalive探測前的tcp空閉時間
if (wsaioctl((unsigned int)s, sio_keepalive_vals,
(lpvoid)&inkeepalive, ulinlen,
(lpvoid)&outkeepalive, uloutlen,
&ulbytesreturn, null, null) == socket_error)
printf ("%d/n",info.tcpi_state);
if (info.tcpi_state == tcp_established) return 0; /* established */
else return -1;
}
Tcp 斷開連線
tcp協議規定,對於已經建立的連線,網路雙方要進行四次握手才能成功斷開連線,如果缺少了其中某個步驟,將會使連線處於假死狀態,連線本身占用的資源不會被釋放。網路伺服器程式要同時管理大量連線,所以很有必要保證無用連線完全斷開,否則大量僵死的連線會浪費許多伺服器資源。在眾多tcp狀態中,最值得注意的狀態有...
tcp的連線斷開
tcp的斷開連線是需要主機完成四次揮手的過程的,並不是斷網了就表示斷開連線了。假如雙方已經建立起了連線,突然一方斷網 比如突然停電,或者網線突然被拔了 對於另一方來講他並不會知道這個情況,他依然認為連線是沒有斷開的。四次揮手的過程是由系統完成的。如果要斷開連線,要麼是程序發起系統呼叫。或者,這個程序...
TCP如何有效地檢測到一方的非正常斷開?
採用tcp連線的c s模式軟體,連線的雙方在連線空閒狀態時,如果任意一方意外崩潰 當機 網線斷開或路由器故障,另一方無法得知tcp連線已經失效,除非繼續在此連線上傳送資料導致錯誤返回。很多時候,這不是我們需要的。我們希望伺服器端和客戶端都能及時有效地檢測到連線失效,然後優雅地完成一些清理工作並把錯誤...