日期:2014-05-20  浏览次数:21068 次

Socket里面设置Timeout,时间未到就抛出read timed out异常。


我已经设置了Socket.setSoTimeout(3600000);////超时时间为一个小时。

当正常通信20几到30分钟的时候,服务器端就出现上面的异常场。

另外,有个非常严重的问题客户端此时不知道连接已经断掉,仍然处于连接中。客户端采用工业控制的DTU设备。
 
socket 服务器

------解决方案--------------------
TCP的IO超时比较麻烦,要服务端、客户端、网络传输中的各个节点,共同来维护。

如果只有客户端设置了读写空闲超时,并且时间非常长,
那么,网络传输中的某个节点(比如某路由器),可能由于长时间未传输数据,而机械的断开连接,这时,服务端和客户端都不会被感知,客户端还傻等着,服务端一般超时比较短,能够有效的回收相应的资源。

如果网络中间没有转发节点(比如路由器),那么,只有客户端设置超时,并且非常长,
那么,服务端一般也会在长时间未收到消息,而断开连接(服务端读超时)。

SoTimeout是用于维护TCP连接资源的一个重要参数,其设计目的主要是当网络断开或者通讯一方发生意外故障时,另一方能够及时的被感应到,所以,这个参数一般都尽可能的设置的短一些,越短说明对网络通讯状态的变化越敏感。

楼主增大这个参数的想法有些不可取,其目的应该是想较长时间的维持一个TCP连接,我们针对这种情况,通常都是在SoTimeout的1/3时间周期内,发送维持连接包给对方,对方收到这个包时,不错过多处理。其实就是一个垃圾数据,这个数据发送过去,可以激活中间转发节点和接收端的计时器,防止连接断开。当然,这个包也是要定时发送的,空闲才发送的。