java.net.Socket 如果使用 4 参数版本而不是 2 参数版本,构造函数将抛出 Socket 异常

java.net.Socket constructor throws Socket exception if using 4 parameter version but not with 2 parameter version

尝试使用套接字,我发现了以下问题。这个节目:

public class TestSocket {

    private static final String remoteHost = "gmail-smtp-in.l.google.com";
    private static final int port = 25;

    public static void main(String[] args) throws UnknownHostException, IOException {
        System.out.println("Remote: " + InetAddress.getByName(remoteHost));
        System.out.println("Local: " + InetAddress.getByName("localhost"));

        Socket socket = new Socket(InetAddress.getByName(remoteHost), port, InetAddress.getByName("localhost"), 0);


        OutputStream out = socket.getOutputStream();
        InputStream in = socket.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        PrintWriter pw = new PrintWriter(out);
        System.out.println("Server --> " + reader.readLine());
        pw.println("helo localhost");
        System.out.println("Sent 'helo localhost'");
        socket.close();
    }

}

在套接字构造函数的行中抛出异常 java.net.SocketException: Network is unreachable: connect。但是,在尝试使用 telnet 和 netcat 之后,我已经验证服务器可以访问并发送数据。所以这是构造函数的问题。当我将其更改为以下程序时,程序可以运行并能够连接:

Socket socket = new Socket(InetAddress.getByName(remoteHost), port);

我不明白是什么造成了差异。这第二个构造函数是否也应该绑定到本地主机上的临时端口,就像第一个将 0 作为端口传递时一样?为什么一个有效,另一个无效?

编辑:在Windows10.

上使用Java1.8.0_112

public Socket(InetAddress host, int port, InetAddress interface, int localPort) throws IOException

此套接字连接到前两个参数中指定的主机和端口。它从最后两个参数指定的本地网络接口和端口连接。

所以,您正在尝试从本地主机连接到 public 地址,这根本没有意义。此构造函数的最后 2 个参数要求选择要连接的本地接口。


选择这种创建套接字方式的用例说明:

假设您正在编写一个程序来定期将错误日志转储到打印机或通过内部邮件服务器发送它们。您需要确保使用的是向内网络接口而不是向外网络接口。所以,在这种情况下,你会 select 这种构造套接字的方式。