有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

为什么是java。网SocketException:socket在java之后关闭。网ConnectException:连接被拒绝'?

我正在尝试连接到一个远程主机,一遍又一遍地等待它出现。然而,在一次连接被拒绝的异常之后(因为服务器还没有运行),它会持续抛出socket关闭异常。为什么插座会被关闭?socket应该与调用失败的connect()之前处于相同的状态,不是吗

                while(!tcpSock.isConnected()) {
                    try {
                        tcpSock.connect(destination);
                    } catch (SocketException e) {
                        System.err.println(e.toString());
                    }
                }

导致

Setting TCP client mode connecting to remote host localhost/127.0.0.1 port 4500
java.net.ConnectException: Connection refused: connect
java.net.SocketException: Socket closed
java.net.SocketException: Socket closed
java.net.SocketException: Socket closed
java.net.SocketException: Socket closed

期望的行为是

Setting TCP client mode connecting to remote host localhost/127.0.0.1 port 4500
java.net.ConnectException: Connection refused: connect
java.net.ConnectException: Connection refused: connect
java.net.ConnectException: Connection refused: connect
java.net.ConnectException: Connection refused: connect
Established connection to: localhost port 4500

(调试完成后,我将注释掉异常的打印内容。)


共 (1) 个答案

  1. # 1 楼答案

    看看OpenJDK源代码。。。当connect(...)调用失败时,SocketImpl代码调用Socket上的close()

    这是Java 11中的代码(在java.net.AbstractPlainSocketImpl):

    protected void connect(String host, int port)
        throws UnknownHostException, IOException
    {
        boolean connected = false;
        try {
            InetAddress address = InetAddress.getByName(host);
            this.port = port;
            this.address = address;
    
            connectToAddress(address, port, timeout);
            connected = true;
        } finally {
            if (!connected) {
                try {
                    close();  // <<   HERE
                } catch (IOException ioe) {
                    /* Do nothing. If connect threw an exception then
                       it will be passed up the call stack */
                }
            }
        }
    }
    

    SocketImpl对象的close()调用会导致Socket被标记为关闭


    简而言之,Java Socket对象不支持在连接尝试失败后重试。如果要重试,代码需要创建一个新的Socket对象

    关于Socket这样做是否正确的讨论是无关紧要的。只是。。。而且这种情况极不可能改变。唯一可能改变的是,他们可能会在Socketjavadocs中记录这种行为