?? tcpshutup.txt
字號(hào):
2007/1/26
TCP連接非正常斷開(kāi)的檢測(cè)(KeepAlive探測(cè))
此處的”非正常斷開(kāi)”指TCP連接不是以優(yōu)雅的方式斷開(kāi),如網(wǎng)線故障等物理鏈路的原因,還有突然主機(jī)斷電等原因
有兩種方法可以檢測(cè):1.TCP連接雙方定時(shí)發(fā)握手消息 2.利用TCP協(xié)議棧中的KeepAlive探測(cè)
第二種方法簡(jiǎn)單可靠,只需對(duì)TCP連接兩個(gè)Socket設(shè)定KeepAlive探測(cè),所以本文只講第二種方法在Linux,Window2000下的實(shí)現(xiàn)(在其它的平臺(tái)上沒(méi)有作進(jìn)一步的測(cè)試)
Windows 2000平臺(tái)下
//定義結(jié)構(gòu)及宏
struct TCP_KEEPALIVE {
u_longonoff;
u_longkeepalivetime;
u_longkeepaliveinterval;
} ;
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
//KeepAlive實(shí)現(xiàn)
TCP_KEEPALIVE inKeepAlive = {0}; //輸入?yún)?shù)
unsigned long ulInLen = sizeof(TCP_KEEPALIVE);
TCP_KEEPALIVE outKeepAlive = {0}; //輸出參數(shù)
unsigned long ulOutLen = sizeof(TCP_KEEPALIVE);
unsigned long ulBytesReturn = 0;
//設(shè)置socket的keep alive為5秒,并且發(fā)送次數(shù)為3次
inKeepAlive.onoff = 1;
inKeepAlive.keepaliveinterval = 5000; //兩次KeepAlive探測(cè)間的時(shí)間間隔
inKeepAlive.keepalivetime = 5000; //開(kāi)始首次KeepAlive探測(cè)前的TCP空閉時(shí)間
if (WSAIoctl((unsigned int)s, SIO_KEEPALIVE_VALS,
(LPVOID)&inKeepAlive, ulInLen,
(LPVOID)&outKeepAlive, ulOutLen,
&ulBytesReturn, NULL, NULL) == SOCKET_ERROR)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%P|%t) \WSAIoctl failed. error code(%d)!\n"),WSAGetLastError()));
}
Linux平臺(tái)下
#include
……
////KeepAlive實(shí)現(xiàn)
//下面代碼要求有ACE,如果沒(méi)有包含ACE,則請(qǐng)把用到的ACE函數(shù)改成linux相應(yīng)的接口
int keepAlive = 1;//設(shè)定KeepAlive
int keepIdle = 5;//開(kāi)始首次KeepAlive探測(cè)前的TCP空閉時(shí)間
int keepInterval = 5;//兩次KeepAlive探測(cè)間的時(shí)間間隔
int keepCount = 3;//判定斷開(kāi)前的KeepAlive探測(cè)次數(shù)
if(setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive)) == -1)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%P|%t) setsockopt SO_KEEPALIVE error!\n")));
}
if(setsockopt(s,SOL_TCP,TCP_KEEPIDLE,(void *)&keepIdle,sizeof(keepIdle)) == -1)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%P|%t) setsockopt TCP_KEEPIDLE error!\n")));
}
if(setsockopt(s,SOL_TCP,TCP_KEEPINTVL,(void *)&keepInterval,sizeof(keepInterval)) == -1)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%P|%t) setsockopt TCP_KEEPINTVL error!\n")));
}
if(setsockopt(s,SOL_TCP,TCP_KEEPCNT,(void *)&keepCount,sizeof(keepCount)) == -1)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%P|%t)setsockopt TCP_KEEPCNT error!\n")));
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -