从Localhost到google.com构建套接字时出现错误



我正在java中运行套接字编程,我面临的问题如下所示的代码,使我的localhost和google.com之间的套接字连接,但得到以下错误。我不确定代码中有什么问题。

If I am using LocalHost address as
String x = Inet4Address.getLocalHost().getHostAddress().toString(); 
then its running fine.
//code
public class SocketConnection {
/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    SocketConnection tl= new SocketConnection();
    tl.connect();
}

public void connect()
{
    try {
        String x = Inet4Address.getLoopbackAddress().getHostAddress().toString();
        InetAddress addr = InetAddress.getByName(x);
        System.out.println(addr);
        Socket socket = new Socket("www.google.com", 80, addr , 59645);
        socket.close();
    } catch (Exception e) {
       e.printStackTrace();
    }
}

错误信息是

/127.0.0.1
java.net.NoRouteToHostException: Can't assign requested address
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:286)
at SocketConnection.connect(SocketConnection.java:36)
at SocketConnection.main(SocketConnection.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

"localhost"是一个特殊的虚拟接口,只有将机器连接到自己。你不能通过它启动到google.com的连接。如果您想要启动到google.com的连接,您必须从一个以某种方式实际连接到Internet的接口进行连接。

如果您将Socket socket = new Socket("www.google.com", 80, addr, 59645);替换为Socket socket = new Socket("www.google.com", 80);,您应该能够使用该目的地的操作系统默认接口打开该套接字,但随后源端口将被随机选择。

如果你想控制源端口,你可以这样做:Socket socket = new Socket("www.google.com", 80, InetAddress.getByName("0.0.0.0"), 59645);

从网络的角度来看,你试图构建的东西没有意义。

远程主机名和端口是OK的。问题是您提供的作为源地址的IP地址是环回地址。它的意思是"这个主人"。它不能从您的机器外部路由到。(或者更准确地说,如果"google.com"主机确实向"127.0.0.1"发送了一个数据包,它将与自己对话!)

您需要提供与将从您的主机发送数据包的网卡相对应的IP地址。一个简单的方法是修改如下:

    String x = Inet4Address.getLoopbackAddress().getHostAddress().toString();
    InetAddress addr = InetAddress.getByName(x);

:

    InetAddress addr = InetAddress.getLocalHost();

或者更简单,在创建套接字时不指定源地址和端口。让操作系统来处理。


如果您确实需要,您可以使用NetworkInterface类(javadoc)枚举系统中所有已配置的网络接口,并尝试根据其绑定IP地址的属性选择一个合适的接口。然而,要可靠地做到这一点,您需要了解您的网络拓扑/路由,我认为没有一种方法可以获得该信息。如果由于某种原因,getLocalHost调用返回了错误的IP地址,那么通过属性、命令行参数或类似的方法来配置正确的IP地址会更简单。

最新更新