Keep_Alive(TCP协议)

当连接已经建立,如不采取任何措施,则无法确认对端是没有发送数据还是已经掉线,所以需要主动确认对端是否存活。如果对端已经掉线还持续占用连接,影响是非常大的。

Keep_Alive可以设定时间间隔主动发送心跳包,如果长期无回应则释放连接。

BOOL Keep_Alive(SOCKET sock)
{
    int					SetSockRet = 0;
    int					WSActl = 0;
    BOOL				KeepALiveSet = TRUE;
    DWORD				IBRet;

    struct tcp_keepalive alive_in;     
    struct tcp_keepalive alive_out;
    alive_in.onoff = 1;                //0为开启,1为关闭
    alive_in.keepalivetime = 30000;    //多长时间(ms)没有数据传输就开始发送心跳包
    alive_in.keepaliveinterval = 2000; //每隔多长时间(ms)send一个心跳包,发5次(系统值)

    SetSockRet = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&KeepALiveSet, sizeof(KeepALiveSet));                 //设置KEEPALIVE,默认为2小时没有数据传输开始检测
    if (SetSockRet == SOCKET_ERROR)
    {
        printf("setsockopt failed\n");
        return FALSE;
    }
    WSActl = WSAIoctl(
        sock,               //参数1:Socket
        SIO_KEEPALIVE_VALS, //参数2:要执行的操作的控制代码
        &alive_in,          //参数3:指向输入缓冲区的指针
        sizeof(alive_in),   //参数4:输入缓冲区的大小(以字节为单位)
        &alive_out,         //参数5:指向输出缓冲区的指针
        sizeof(alive_out),  //参数6:输出缓冲区的大小(以字节为单位)
        &IBRet,             //参数7:指向实际输出字节数的指针
        NULL, 
        NULL
    );
    if (WSActl == SOCKET_ERROR)
    {
        printf("WSAIoctl failed\n");
        return FALSE;
    }
    return TRUE;
}