tcp长连接判断对方断开的方法

1、心跳包

2、keepalive检测,对于设置了keepalive来说,tcp检测到对端socket不再可用时(不能发出探测包,或探测包没有收到ACK的响应包),select会返回socket可读,并且在recv时返回-1,同时置上errnoETIMEDOUT。此时TCP的状态是断开的。

struct TCP_KEEPALIVE {
    unsigned long onoff;
    unsigned long keepalivetime;
    unsigned long keepaliveinterval;
} ;

#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)

/* KeepAlive实现 */
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 ;
    }
    /* 输入参数 */
    struct TCP_KEEPALIVE inKeepAlive = {0}; 
    unsigned long ulInLen = sizeof(struct TCP_KEEPALIVE);

    /* 输出参数 */
    struct TCP_KEEPALIVE outKeepAlive = {0}; 
    unsigned long ulOutLen = sizeof(struct TCP_KEEPALIVE);
    unsigned long ulBytesReturn = 0;
    int ret = 0;

    /* 设置keepalive 为5秒,并且发送次数为3次 */
    inKeepAlive.onoff             = 1;
    /* 2次keepalive探测间隔时间 */
    inKeepAlive.keepaliveinterval = 5000; 
    /* 开始首次keepalive探测前的tcp空闲时间 */
    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: %d\n", WSAGetLastError());
    }
}






你可能感兴趣的:(socket,struct,tcp,IOC,null)