golang判斷tcp是否斷開的方法:
keepalive檢測,對于設(shè)置了keepalive來說,當(dāng)tcp檢測到對端socket不再可用時(shí)(不能發(fā)出探測包,或探測包沒有收到ACK的響應(yīng)包),select會返回socket可讀,并且在recv時(shí)返回-1,同時(shí)置上errno為ETIMEDOUT。此時(shí)TCP的狀態(tài)是斷開的。
struct TCP_KEEPALIVE { unsigned long onoff; unsigned long keepalivetime; unsigned long keepaliveinterval; } ; #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) /* KeepAlive實(shí)現(xiàn) */ void set_keepalive (SOCKET s) { BOOL bKeepAlive = TRUE; int nRet = ::setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char*)&bKeepAlive, sizeof(bKeepAlive)); if (nRet == SOCKET_ERROR) { return ; } /* 輸入?yún)?shù) */ struct TCP_KEEPALIVE inKeepAlive = {0}; unsigned long ulInLen = sizeof(struct TCP_KEEPALIVE); /* 輸出參數(shù) */ struct TCP_KEEPALIVE outKeepAlive = {0}; unsigned long ulOutLen = sizeof(struct TCP_KEEPALIVE); unsigned long ulBytesReturn = 0; int ret = 0; /* 設(shè)置keepalive 為5秒,并且發(fā)送次數(shù)為3次 */ inKeepAlive.onoff = 1; /* 2次keepalive探測間隔時(shí)間 */ inKeepAlive.keepaliveinterval = 5000; /* 開始首次keepalive探測前的tcp空閑時(shí)間 */ inKeepAlive.keepalivetime = 5000; ret = WSAIoctl((unsigned int)s, SIO_KEEPALIVE_VALS, (LPVOID)&inKeepAlive, ulInLen, (LPVOID)&outKeepAlive, ulOutLen, &ulBytesReturn, NULL, NULL); if (ret == SOCKET_ERROR) { printf ("error: %dn", WSAGetLastError()); } }