未设置接受连接的“超时时间”时接受超时异常

时间:2017-09-13 09:20:02

标签: java

我们正在使用TCP服务器。有时我们会遇到异常

java.net.SocketTimeoutException: Accept timed out
        at java.net.PlainSocketImpl.socketAccept(Native Method)
        at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
        at java.net.ServerSocket.implAccept(ServerSocket.java:530)
        at java.net.ServerSocket.accept(ServerSocket.java:498)

我用Google搜索了一下,发现它超过了由setSoTimeout(timeinmilli)方法设置的时间。但是,我们没有调用那种方法。

示例tcp服务器:

class TCPServer
    {   
        public static void main(String args[]){
            public void initializeConnectionHandler(String ip, int port) {
                try{            
                    ServerSocket serverSocket = new ServerSocket(port, serverSocket_backlog, InetAddress.getByName(ip));            
                    log("Waiting for client on port: " +serverSocket.getLocalPort());
                    while(true){
                        Socket socket = serverSocket.accept();
                        log("Just connected to "+ socket.getRemoteSocketAddress());
                        Runnable tcpConnectionHandler = new TCPConnectionHandler(serverSocket, socket, workerManager);
                        new Thread(tcpConnectionHandler).start();
                    }       
                }
                catch (Exception e){
                    log("Exception occured while initializing ConnectionHandlers: "+e);
                    logException(e);
                    System.exit(0);
                }
            }
        }
    }

2 个答案:

答案 0 :(得分:1)

您是正确的,只有在您通过调用setSoTimeout设置超时后,才会发生此异常。然而,如果您浏览搜索结果,您可以在您看到它时偶尔讨论这种效果,例如:在Tomcat,他们认为他们在JVM中发现了一个错误并添加了一个解决方法来保持服​​务器运行。

使用Jenkins报告此异常的另一个结果(德语,抱歉)表明IPv6也处于活动状态时可能存在问题。解决方法是将系统属性java.net.preferIPv4Stack设置为true

我不是后者的粉丝"解决方案"但是关于Tomcat团队实施的解决方法,我建议你也这样做。至少,如果发生此类异常,请不要停止整个循环。

答案 1 :(得分:1)

在内部,它正在调用socketAccept类的TwoStacksPlainSocketImpl方法。

java.net.SocketTimeoutException: Accept timed out
        at java.net.PlainSocketImpl.socketAccept(Native Method)
        at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)
        at java.net.ServerSocket.implAccept(ServerSocket.java:530)
        at java.net.ServerSocket.accept(ServerSocket.java:498)

方法是原生的,因此您无法完全找到原因,但下面是openjdk的本机代码。

https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/windows/native/java/net/TwoStacksPlainSocketImpl.c

你可以发现它抛出了提到的异常。