Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“的含义;java.io.IOException:连接超时;连接阶段后_Java_Sockets_Nio - Fatal编程技术网

“的含义;java.io.IOException:连接超时;连接阶段后

“的含义;java.io.IOException:连接超时;连接阶段后,java,sockets,nio,Java,Sockets,Nio,可能与以下方面有关: 我已经使用nio编写了一个java服务器应用程序 我将客户端连接到服务器应用程序,并拔下客户端的网络电缆。在服务器端,我没有立即得到任何异常,但经过一段时间(8分钟左右),我得到一个“IOException:连接超时” 以下是部分堆栈跟踪: java.io.IOException: Connection timed out at sun.nio.ch.FileDispatcherImpl.read0(Native Method) at sun.nio.ch.

可能与以下方面有关:

我已经使用nio编写了一个java服务器应用程序

我将客户端连接到服务器应用程序,并拔下客户端的网络电缆。在服务器端,我没有立即得到任何异常,但经过一段时间(8分钟左右),我得到一个“IOException:连接超时”

以下是部分堆栈跟踪:

java.io.IOException: Connection timed out
    at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
    at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
    at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:225)
    at sun.nio.ch.IOUtil.read(IOUtil.java:198)
    at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:375)
........
直到现在,当我看到netstat输出时,我看到这个特定客户机连接的套接字状态显示为已建立

问题是:

  • 这个超时是可配置的吗

  • 为什么netstat输出显示已建立的套接字状态?理想情况下,它应该关闭\u等待(当客户端断开连接时)


  • 因为CLOSE_WAIT状态是指一个FI在等待来自对等方的对应FIN,而这里不是这种情况


    这很可能是可配置的

    超时通常是不可配置的,因为它取决于操作系统提供的可能性Unix通常不允许进程修复连接超时,并且通常将其修复为大约两分钟。也许某些版本的linux/BSD系统允许配置此功能,但这是不可移植的,通常不允许将其修复给用户(仅管理员)。这与每次尝试使用的重传次数和超时有关,并且受TCP实现的独占控制

    当您完成连接时,会经历两种非超时状态(FIN\u WAITTIME\u WAIT)。两种方法中的第一种是获取另一端的响应(您可以关闭连接的一端,告诉另一端您不打算发送更多数据,但您必须等待另一端执行相同的操作)TIME\u wait是内核为处理(并丢弃)关闭的连接而维护的一种特殊状态连接关闭后,最后一帧的所有可能的重新传输都将继续进行。他们与超时无关

    tcp连接没有隐式超时。如果两台机器没有任何信息可传输,它们可以在不交换任何信息的情况下度过数周。您可以通过一个套接字选项(SO_KEEPALIVE)控制silenting连接之间某种心跳的使用,以检查它们的活动性。该选项使两侧的TCP交换空数据包,以了解另一侧是否仍然活动。同样,您只能控制此数据包的使用,而不能控制关闭连接的频率或丢失帧的数量(这可以在linux中配置,但只能在管理员模式下接触内核配置)

    注1(对@Krishna Chaitanya P的答复) 如果拔掉电缆插头后不久出现异常,可能是以下两个原因之一:

  • 您继续写入该连接,发送缓冲区在没有得到及时确认的情况下被填满(这是很少见的,因为发生这种情况时,您的进程通常会在write(2)系统调用中被阻塞),并且确实发生了一些超时(在套接字的java实现中)
  • tcp套接字的java实现使用了SO_KEEPALIVE选项(最可能的事情)。正如我之前所说的,您可以使用或不使用布尔控件,但是您无法调整保持连接的时间间隔或断开连接的次数。尝试调用套接字类上的getKeepAlive()/setKeepAlive(布尔)方法来控制此功能。我在文档中没有看到连接的套接字在默认情况下是否处于keepalive状态。到目前为止,这是服务器中常用的选项,因为它允许断开失去连接的客户端,而无需通知服务器

  • 根据我的经验,连接的套接字发生此异常的原因总是由于防火墙关闭空闲时间过长的连接。我特别在云环境(AWS、Rackspace)中看到过这种情况,但并不限于此。最有可能的情况是,两个连接对等方之间存在某种防火墙,这会在一段时间后关闭空闲连接

    理想情况下的最佳修复方法是更改防火墙配置,前提是您或运营团队有权访问防火墙。在任何情况下,如果您可以在代码中处理该用例,并优雅地终止与其他对等方的通信,那就更好了

  • 不,它是不可配置的。这是重新传输超时的结果。除非应用程序继续写入,或者在断开连接时有挂起的写入,否则这种情况根本不会发生

  • 它不应该靠近,因为没有收到FIN。因此,它应该被建立起来


  • 否。处于关闭等待状态的端口已从对等方接收FIN,并正在等待本地应用程序关闭。这绝对是不可配置的。如果等待关闭的进程没有关闭,为什么要用超时事件来中断它?关闭(2)调用不可能丢失信息,以便通知进程它没有关闭套接字以使超时成为必要。超时是可配置的,不是在应用程序中,而是在操作系统级别-查看tcp的Linux手册页以获取参数tcp_retries1和tcp_retries2。正如我已经提到的,我手动拔下了电缆。我在客户端和服务器之间没有防火墙,它们是直接连接的。在这种情况下,防火墙正在发送带有正确序列号(在两个方向)和RST标志的空tcp段,因此通过它的干预主动重置连接。当表中的NAT项超时时,可能会发生这种情况,但实现这种情况并不常见。