我在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)
答案 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地址会更简单。