关于检测SOCKET的异常断线
2010-01-30 15:45
253 查看
我的服务器代码中有类似的接收语句:
do {
FD_ZERO(&read_fds);
FD_SET((unsigned int)sock, &read_fds);
FD_ZERO(&write_fds);
if (out_queue)
FD_SET((unsigned int)sock, &write_fds);
tm.tv_sec = 0;
tm.tv_usec = 50;
count = select(sock + 1, &read_fds, &write_fds, NULL, &tm);
} while (count == 0);
if (FD_ISSET((unsigned int)sock, &read_fds)) {
// Try to read some data in
bytes = Read(buff, currlen);
...
}
1)当客户端以PC形式登录时,断开客户端的网线,能够跳出select的循环,并在read中判断出错误,并得到socket断线信息
2)当客户端以手机形式登录时(使用wifi),断开客户端的wifi连接,则始终不能跳出select循环,至少测试过等待5分钟后仍不能跳出,count始终为0.
于是从网上搜索的相关的讨论话题,发现这确实是一个很普遍的问题,很多的描述与此类似。一个基本的思路是靠在send中发送数据来检测断线,但在我的应用中没有心跳包,不便使用send判断。
为此找到了一篇官方文档,在http://support.microsoft.com/kb/140325,感觉到必须使用KEEPALIVE来尝试,为此加入了相关的代码进行实验,很幸运,实验成功!
需要加入的代码是:
#ifdef __WIN32__
tcp_keepalive inKeepAlive = {0};
unsigned long ulInLen = sizeof(tcp_keepalive);
tcp_keepalive outKeepAlive = {0};
unsigned long ulOutLen = sizeof(tcp_keepalive);
unsigned long ulBytesReturn = 0;
inKeepAlive.onoff = 1;
inKeepAlive.keepaliveinterval = 1000;
inKeepAlive.keepalivetime = 60000;
if (SOCKET_ERROR == WSAIoctl(sock, SIO_KEEPALIVE_VALS,
(LPVOID)&inKeepAlive, ulInLen,
(LPVOID)&outKeepAlive, ulOutLen,
&ulBytesReturn, NULL, NULL))
{
}
#endif
此后,当手机侧的WIFI手动关闭或按下电源键黑屏后,确实约1分钟后,select函数返回并在read中得到WSAECONNRESET异常!
do {
FD_ZERO(&read_fds);
FD_SET((unsigned int)sock, &read_fds);
FD_ZERO(&write_fds);
if (out_queue)
FD_SET((unsigned int)sock, &write_fds);
tm.tv_sec = 0;
tm.tv_usec = 50;
count = select(sock + 1, &read_fds, &write_fds, NULL, &tm);
} while (count == 0);
if (FD_ISSET((unsigned int)sock, &read_fds)) {
// Try to read some data in
bytes = Read(buff, currlen);
...
}
1)当客户端以PC形式登录时,断开客户端的网线,能够跳出select的循环,并在read中判断出错误,并得到socket断线信息
2)当客户端以手机形式登录时(使用wifi),断开客户端的wifi连接,则始终不能跳出select循环,至少测试过等待5分钟后仍不能跳出,count始终为0.
于是从网上搜索的相关的讨论话题,发现这确实是一个很普遍的问题,很多的描述与此类似。一个基本的思路是靠在send中发送数据来检测断线,但在我的应用中没有心跳包,不便使用send判断。
为此找到了一篇官方文档,在http://support.microsoft.com/kb/140325,感觉到必须使用KEEPALIVE来尝试,为此加入了相关的代码进行实验,很幸运,实验成功!
需要加入的代码是:
#ifdef __WIN32__
tcp_keepalive inKeepAlive = {0};
unsigned long ulInLen = sizeof(tcp_keepalive);
tcp_keepalive outKeepAlive = {0};
unsigned long ulOutLen = sizeof(tcp_keepalive);
unsigned long ulBytesReturn = 0;
inKeepAlive.onoff = 1;
inKeepAlive.keepaliveinterval = 1000;
inKeepAlive.keepalivetime = 60000;
if (SOCKET_ERROR == WSAIoctl(sock, SIO_KEEPALIVE_VALS,
(LPVOID)&inKeepAlive, ulInLen,
(LPVOID)&outKeepAlive, ulOutLen,
&ulBytesReturn, NULL, NULL))
{
}
#endif
此后,当手机侧的WIFI手动关闭或按下电源键黑屏后,确实约1分钟后,select函数返回并在read中得到WSAECONNRESET异常!
相关文章推荐
- socket选项自带的TCP异常断开检测
- Socket心跳包异常检测的C语言实现,服务器与客户端代码案例
- 关于Magick++ 在readImage过程中异常抛出检测 Magick::readImage return exception
- 关于错误:ORA-12592: TNS: 包错误 和 Io 异常: Connection reset by peer: socket write error
- socket 断线检测 心跳检测
- SOCKET 检测链接是否断线的三种方法(转载)
- socket用户异常掉线检测
- Android关于Socket通信异常的问题
- 关于socket tcp 断线重连
- 关于java网络编程中 java.net.SocketException: Connection reset 异常的原因
- 关于Socket链接服务器可能产生的异常
- 关于WSARECV与WSASEND,SOCKET_ERROR关闭997异常的问题
- 关于R与Tableau的集成----异常值检测
- [转] Socket心跳包异常检测的C语言实现,服务器与客户端代码案例
- 关于socket编程中服务器端如何检测客户端连接断开的问题
- socket用户异常掉线检测
- 关于socket tcp 断线重连
- socket选项自带的TCP异常断开检测
- socket选项自带的TCP异常断开检测
- socket用户异常掉线检测