`
uo153uo
  • 浏览: 19518 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

Socket与拔掉网线

 
阅读更多

Socket与拔掉网线
2011年09月18日
  当客户端与服务端通过Tcp Socket进行通信时,如果客户端应用正常退出或异常退出,服务端都会在对应的连接上获取感知(如返回0、或抛出异常)。但是,如果客户端的网线被拔掉,那么,默认情况下,服务端需要在2个小时后才会感知客户端掉线。对于很多服务端应用程序来说,这么长的反应时间是不能忍受的。
  我们通常在应用层使用“心跳机制”来解决类似的问题,这是可行的。
  然而,在这里,我们可以使用Socket自己的心跳机制来解决这一问题。 System.Net.Sockets.Socket提供了IOControl()方法给我们来设置Sokect的心跳机制的相关参数。比如,我们设置KeepAlive的时间为20秒,检查间隔为2秒。可以这样做:
  int keepAlive = -1744830460; // SIO_KEEPALIVE_VALS
  byte[] inValue = new byte[] { 1, 0, 0, 0, 0x20, 0x4e, 0, 0, 0xd0, 0x07, 0, 0 }; //True, 20 秒, 2 秒
  sock.IOControl(keepAlive, inValue, null);
  20秒(20000毫秒)的16进制表示是4e20,2秒(2000毫秒)的16进制表示是07d0,如此,你可以修改inValue参数为自己希望的值。
  在上述设置下,如果拨掉客户端网线,服务器Socket.Receive()会在20秒后抛出异常。
  QUOTE:
  原帖由 mynets 于 2006-11-21 16:25 发表
  TCP protocol has a timer to determine if the connection is abnormally closed. But this timeout value is very long by default and if you want to check this situation as soon as possible to improve p ...
  现在就是不想用 链路维持包 。呵呵。
  不过终于知道很多协议中为什么要有这个东西了。http://bbs.chinaunix.net/thread-859015-1-1.html
  http://blog.csdn.net/fan_hai_ping/article/details/6691560
  最近在做一个TCP采集程序,使用到C/S的结构。功能比较的简单,就是TCP采集程序作为服务器,信令采集设备作为客户端,客户端与服务器端之间建立长连接之后,开始发送信令报文给服务器。在服务器端使用多线程方式来处理每个客户端的socket连接,服务器端不主动断开链路,也没有心跳机制来维护连接的状态,客户端发送数据的时间也是不一定的,只要有采集到信令数据时才进行发送。在客户端socket断开后,服务器端应该能够知道并且释放socket资源。
  判断socket是否已经断开的方法是使用非阻塞的select方式进行socket检查,步骤如下:
  1)设置接收到的socket为异步方式;
  2)使用select()函数测试一个socket是否可读;
  3)如果select()函数返回的值为1,但是使用recv()函数读取的数据长度为0,那么说明该socket已经断开。
  如果recv()返回值小于等于0时,客户端的连接已经断开,但是还需要判断errno是否等于EINTR。如果errno=EINTR则说明recv()函数是由于程序接收到中断信号后返回的,socket连接应该还是正常,步应该close掉socket连接。
  注:对于阻塞socket的recv函数会在以下三种情况下返回值:
  1)接收到数据时会返回;
  2)程序接收到信号时返回-1,errno=EINTR;
  3)Socket出现问题时,返回-1,具体的错误码请查看man recv;
  4)一定要养成查看man说明,内容很详细,很有帮助。
  这种方法经过长时间的测试证明是有效的,仅供大家参考。
  此外,UNP卷一上有很多socket异常情况下的模拟解释,大家可以去阅读下。如果网络中间有多级路由,路由当掉等很多情况出现,所以建议程序中在应用层中加入心跳(heartbeat机制)和重连来维持连接的状态。
  TCP protocol has a timer to determine if the connection is abnormally closed. But this timeout value is very long by default and if you want to check this situation as soon as possible to improve performance, the best solution is to introduce a keepalive mechanism in application protocol design.
  TCP协议有一个定时器来决定连接是否被异常关闭。但是该超时时间值缺省的情况下会非常长,如果你希望尽快的检查出这种状态改进性能,最好的方法就是在应用程序协议设计的时候引入keepalive(保持连接)机制。
  分享到:
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics