检测socket链接是否断开
2011-05-17 16:34
246 查看
【解决方案】
1. 发送重试,由业务完成。
因为club_l5的send接口不会保留用户发送的内容,在recv失败的情况下,用户发送的数据已经丢失,所以只能由业务进行重试。
结论:否定。由于后端服务器有多台,每次发送的时候并不能不能保证连接的机器还是上次发送的那一台服务器,有可能后端所有的连接都被断开,虽然失败比例有所降低,还是不能解决问题。
2. 修改服务器端关闭连接的等待时间。
治标不治本,可以在紧急情况下使用。
经过和still、allan、robby、steven一起讨论,最佳的方案就是在发送的时候,就能感知到服务器端已经关闭连接,经过讨论,给出以下解决方案:
3. 在send之前对先对read进行selcect,并使用read检验连接的状态。
在send之前先对select函数read进行select,并设置时间参数设为0,select会立即返回,如果有FIN包可立刻知道,再进行read,如果read的返回值 <= 0,则说明连接有问题,或接收到了fin包,此时需关闭连接进行重连。
4. 使用poll()函数是否处于POLLRDHUP(套接字半关闭)状态。
如果是,则关闭连接进行重连,目前还不完全成熟,且不适用于内核版本较低的系统。
5. 使用系统调用getpeername函数加系统错误码的方式检查对端是否关闭连接。
用法如下:if(getpeername (sock, &addr, &len) < 0 && errno == ENOTCONN) 当此条件成立的时候,说明对端已经关闭连接。
6. 发送之前用MSG_PEEK的方式recv。
看recv的返回值是否0字节,如果是0字节,说明对方发送了fin包,已关闭了连接。allan给出TTC中验证连接是否有效的函数:
view plaincopy to clipboardprint?
01.int CPollerObject::CheckLinkStatus(void)
02.{
03. char msg[1] = {0};
04. int err = 0;
05. err = recv(netfd, msg, sizeof(msg), MSG_DONTWAIT|MSG_PEEK);
06. /* client already close connection. */
07. if(err == 0 || (err < 0 && errno != EAGAIN))
08. return -1;
09. return 0;
10.}
int CPollerObject::CheckLinkStatus(void)
{
char msg[1] = {0};
int err = 0;
err = recv(netfd, msg, sizeof(msg), MSG_DONTWAIT|MSG_PEEK);
/* client already close connection. */
if(err == 0 || (err < 0 && errno != EAGAIN))
return -1;
return 0;
}
综合集中方案,最好采用6方案。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ghosc/archive/2010/07/07/5718978.aspx
1. 发送重试,由业务完成。
因为club_l5的send接口不会保留用户发送的内容,在recv失败的情况下,用户发送的数据已经丢失,所以只能由业务进行重试。
结论:否定。由于后端服务器有多台,每次发送的时候并不能不能保证连接的机器还是上次发送的那一台服务器,有可能后端所有的连接都被断开,虽然失败比例有所降低,还是不能解决问题。
2. 修改服务器端关闭连接的等待时间。
治标不治本,可以在紧急情况下使用。
经过和still、allan、robby、steven一起讨论,最佳的方案就是在发送的时候,就能感知到服务器端已经关闭连接,经过讨论,给出以下解决方案:
3. 在send之前对先对read进行selcect,并使用read检验连接的状态。
在send之前先对select函数read进行select,并设置时间参数设为0,select会立即返回,如果有FIN包可立刻知道,再进行read,如果read的返回值 <= 0,则说明连接有问题,或接收到了fin包,此时需关闭连接进行重连。
4. 使用poll()函数是否处于POLLRDHUP(套接字半关闭)状态。
如果是,则关闭连接进行重连,目前还不完全成熟,且不适用于内核版本较低的系统。
5. 使用系统调用getpeername函数加系统错误码的方式检查对端是否关闭连接。
用法如下:if(getpeername (sock, &addr, &len) < 0 && errno == ENOTCONN) 当此条件成立的时候,说明对端已经关闭连接。
6. 发送之前用MSG_PEEK的方式recv。
看recv的返回值是否0字节,如果是0字节,说明对方发送了fin包,已关闭了连接。allan给出TTC中验证连接是否有效的函数:
view plaincopy to clipboardprint?
01.int CPollerObject::CheckLinkStatus(void)
02.{
03. char msg[1] = {0};
04. int err = 0;
05. err = recv(netfd, msg, sizeof(msg), MSG_DONTWAIT|MSG_PEEK);
06. /* client already close connection. */
07. if(err == 0 || (err < 0 && errno != EAGAIN))
08. return -1;
09. return 0;
10.}
int CPollerObject::CheckLinkStatus(void)
{
char msg[1] = {0};
int err = 0;
err = recv(netfd, msg, sizeof(msg), MSG_DONTWAIT|MSG_PEEK);
/* client already close connection. */
if(err == 0 || (err < 0 && errno != EAGAIN))
return -1;
return 0;
}
综合集中方案,最好采用6方案。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ghosc/archive/2010/07/07/5718978.aspx
相关文章推荐
- 检测socket链接是否断开
- 检测socket链接是否断开
- SOCKET 检测链接是否断线的三种方法
- 自动检测SOCKET链接断开
- JAVA ANDROID SOCKET通信检测(SERVER)连接是否断开
- socket中使用心跳来检测连接是否断开
- Androin学习笔记四十二:Java android Socket通信检测(server)连接是否断开
- SOCKET 检测链接是否断线的三种方法(转载)
- 检测SOCKET是否断开
- C#中判断socket是否已断开的方法
- java中判断socket网络远端是否断开连接
- java中判断socket网络远端是否断开连接
- socket选项自带的TCP异常断开检测
- C# 中用Socket实现判断网络是否断开的实例
- 检测图片链接是否正常
- java中判断socket服务器端是否断开连接
- 关于检测客户端是否断开连接
- C#中判断socket是否已断开的方法
- C 判断socket 是否已经断开
- Socket的3次握手链接与4次断开握手