2016-10-22 64 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

無論您的理由/推理如何,當您與機器外地址通話時,回送地址不會作爲源地址。 –