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