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

时间:2016-10-22 11:32:13

标签: java sockets network-programming

我在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)

2 个答案:

答案 0 :(得分:1)

&#34;本地主机&#34;是一个特殊的虚拟接口,将机器连接到自身。您无法通过它与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);

答案 1 :(得分:1)

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

远程主机名和端口都可以。问题是您提供的IP地址是源地址是环回地址。这意味着“这个主人”。它无法从您的机器外部路由。 (或者更确切地说,如果“google.com”主机确实向“127.0.0.1”发送了一个数据包,它就会自行说话!)

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

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

到此:

    InetAddress addr = InetAddress.getLocalHost();

或者更简单,在创建套接字时不要指定源地址和端口。让操作系统对其进行排序。

如果您确实需要,可以使用NetworkInterface类(javadoc)枚举系统配置的所有网络接口,并尝试根据属性选择合适的网络接口。他们绑定的IP地址。但是,为了可靠地执行此操作,您需要了解网络拓扑/路由,并且我认为没有办法获取该信息。如果由于某种原因,getLocalHost调用返回错误的IP地址,通过属性,命令行参数或类似的东西配置正确的IP地址会更简单。