2016-10-22 62 views
0

我正在Java中运行套接字编程,如下图所示,这使得我的localhost和google.com之间发生套接字连接,但遇到以下错误。我不确定代码中有什么问题。从本地主机到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) 

回答

1

“本地主机”是一种特殊的虚设接口机器连接到其自身。您无法通过它启动与google.com的连接。如果你想启动一个连接到google.com,你必须从一个实际上连接到互联网的接口做到。

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

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

+0

我在我的服务器和20个其他客户端之间建立了一个套接字连接,这两个客户端都位于我的笔记本电脑上(可以认为是多客户端服务器),我试图让所有的客户端在端口80上连接到谷歌服务器来自服务器的消息。来自服务器的消息将全部连接 - google.com,80。当我在我的服务器和客户端之间建立了一个套接字连接时,它向所有具有不同端口号的客户端提供了127.0.0.1的IP地址。这就是为什么我尝试使用分配的端口号使用本地主机IP地址。 –

+0

@AnuvratTiku由于您通过该地址将客户端连接到服务器,因此您的服务器向客户端提供了地址“127.0.0.1”。你仍然无法从127.0.0连接。1'到电脑以外的任何地方。 – Malt

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地址会更简单。

+0

我在我的服务器和20个其他客户端之间建立了一个套接字连接,这两个客户端都位于我的笔记本电脑上(可以认为是多客户端服务器),我试图让所有客户端在端口80连接到谷歌服务器,服务器。来自服务器的消息将全部连接 - google.com,80。当我在我的服务器和客户端之间建立了一个套接字连接时,它向所有具有不同端口号的客户端提供了127.0.0.1的IP地址。这就是为什么我尝试使用分配的端口号使用本地主机IP地址。 –

+0

无论您的理由/推理如何,当您与机器外地址通话时,回送地址不会作为源地址。 –