简体   繁体   中英

Getting an error while building socket from Localhost to google.com

I am running a socket programming in java where I am facing issues with this code as shown below to make socket connection between my localhost and google.com but getting following error. I am not sure what's wrong in the code.

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();
    }
}

The error message is

/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" is a special dummy interface that only connects the machine to itself. You can't initiate a connection to google.com through it. If you want to initiate a connection to google.com , you have to do it from an interface that's actually connected to the Internet somehow.

If you replace Socket socket = new Socket("www.google.com", 80, addr, 59645); with Socket socket = new Socket("www.google.com", 80); , you should be able to open that socket using the operating system's default interface for that destination, but then the source port will be randomly selected.

If you want to control the source port, you can do this: Socket socket = new Socket("www.google.com", 80, InetAddress.getByName("0.0.0.0"), 59645);

What you are trying to build does not make sense from the networking perspective.

The remote hostname and port are OK. The problem is that the IP address your are providing as the source address is the loopback address. It means "this host". It cannot be routed to from outside of your machine. (Or more accurately, if the "google.com" host did send a packet to "127.0.0.1", it would be talking to itself!)

You need to provide the IP address that corresponds to a NIC that will send packets off your host. A simple way to do this is to change this:

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

to this:

    InetAddress addr = InetAddress.getLocalHost();

Or simpler still, don't specify a source address and port when creating the socket. Let the OS sort it out.


If you really needed to, you could use the NetworkInterface class ( javadoc ) to enumerate all of your system's configured network interfaces, and try pick a suitable one based on the properties of their bound IP addresses. However, to do this reliably you need knowledge of your network topology / routing, and I don't think there is a way to obtain that information. If, for some reason, the getLocalHost call returns the wrong IP address, it would be simpler to configure the right one via a property, a command-line argument or something like that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM