1.问题
最近碰到的一个问题,socket连接一台服务器后,如果无数据通讯,服务器会在几分钟后关闭socket。由此产生一个问题。与服务器进行连接后,拔掉网线,几分钟后,由于服务器已经关闭socket,但客户这边还认为已经连接的是正确的socket。因此产生一些操作上的延迟问题。
2.分析
由于服务器已经关闭的客户端的连接,所以客户端也得关闭超时的连接。因此我选用keepalive方法来定时的探测网络是否存在。如果服务器3分钟关闭socket,那客户端只要稍小于3分钟探测一次就可以了。
如果keepalive探测失败,那就可以用select语句捕获到socket需要read,调用一下recv如果返回错误就表示超时了,本socket已经无效,自己进行错误处理了。
还有值得注意的是服务器也必须支持keepalive.单方面那是没有用的。
3.具体代码
本人的客户端是linux2.4.x
keepalive选项的设置是全系统有效的,设置如下
echo 170 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 2 > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo 1 > /proc/sys/net/ipv4/tcp_keepalive_probes
以上增加到系统启动脚本/etc/init.d/****中
tcp_keepalive_time //每次确认包发送的间隔时间
tcp_keepalive_probes//每次确认最多重发次数
tcp_keepalive_intvl //重试间隔
单位秒
//启用socket连接的保持连接包的发送
int iKeepAlive = 1;
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *)&iKeepAlive, sizeof(iKeepAlive));
用select 语句获取read状态,recv返回错误后进行错误处理,具体不在详述了