TCP/IP客户端 - EHOSTUNREACH(无法到达主机)

20

我正在尝试开发一个客户端服务器TCP/IP应用程序。我的PC上运行着一个服务器,移动设备上运行着客户端应用程序。它们都在同一个Wi-Fi网络中,但我无法在它们之间建立连接。在调试客户端Android应用程序时,显示了以下错误:

09-21 01:08:40.422: W/System.err(8536): java.net.ConnectException: failed to connect to /192.168.15.115 (port 4449): connect failed: EHOSTUNREACH (No route to host)
09-21 01:08:40.453: W/System.err(8536):     at libcore.io.IoBridge.connect(IoBridge.java:114)
09-21 01:08:40.453: W/System.err(8536):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
09-21 01:08:40.453: W/System.err(8536):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
09-21 01:08:40.453: W/System.err(8536):     at java.net.Socket.startupSocket(Socket.java:566)
09-21 01:08:40.453: W/System.err(8536):     at java.net.Socket.tryAllAddresses(Socket.java:127)
09-21 01:08:40.453: W/System.err(8536):     at java.net.Socket.<init>(Socket.java:177)
09-21 01:08:40.453: W/System.err(8536):     at java.net.Socket.<init>(Socket.java:149)
09-21 01:08:40.453: W/System.err(8536):     at sabarish.example.client_mobile.MainActivity$1.onClick(MainActivity.java:61)
09-21 01:08:40.453: W/System.err(8536):     at android.view.View.performClick(View.java:3511)
09-21 01:08:40.453: W/System.err(8536):     at android.view.View$PerformClick.run(View.java:14105)
09-21 01:08:40.453: W/System.err(8536):     at android.os.Handler.handleCallback(Handler.java:605)
09-21 01:08:40.453: W/System.err(8536):     at android.os.Handler.dispatchMessage(Handler.java:92)
09-21 01:08:40.453: W/System.err(8536):     at android.os.Looper.loop(Looper.java:137)
09-21 01:08:40.453: W/System.err(8536):     at android.app.ActivityThread.main(ActivityThread.java:4424)
09-21 01:08:40.453: W/System.err(8536):     at java.lang.reflect.Method.invokeNative(Native Method)
09-21 01:08:40.453: W/System.err(8536):     at java.lang.reflect.Method.invoke(Method.java:511)
09-21 01:08:40.453: W/System.err(8536):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-21 01:08:40.453: W/System.err(8536):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-21 01:08:40.453: W/System.err(8536):     at dalvik.system.NativeStart.main(Native Method)
09-21 01:08:40.457: W/System.err(8536): Caused by: libcore.io.ErrnoException: connect failed: EHOSTUNREACH (No route to host)
09-21 01:08:40.457: W/System.err(8536):     at libcore.io.Posix.connect(Native Method)
09-21 01:08:40.457: W/System.err(8536):     at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)
09-21 01:08:40.457: W/System.err(8536):     at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
09-21 01:08:40.457: W/System.err(8536):     at libcore.io.IoBridge.connect(IoBridge.java:112)
09-21 01:08:40.457: W/System.err(8536):     ... 18 more

我正在使用的代码:

public class MainActivity extends Activity {
    private Socket client;
    private PrintWriter printwriter;
    private EditText textField;
    private Button button;
    private String messsage;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textField = (EditText) findViewById(R.id.editText1); //reference to the text field
        button = (Button) findViewById(R.id.button1); //reference to the send button

        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                messsage = textField.getText().toString(); //get the text message on the text field
                textField.setText("");      //Reset the text field to blank

                try {
                    client = new Socket("192.168.15.115", 4449);  //connect to server
                    printwriter = new PrintWriter(client.getOutputStream(),true);
                    printwriter.write(messsage);  //write the message to output stream

                    printwriter.flush();
                    printwriter.close();
                    client.close();   //closing the connection

                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }); 
    }
}

我做错了什么?


1
解除您电脑端的防火墙限制,很可能是端口被阻止了...请确认并检查您的私有IP地址是否在192.168.x.y范围内,并且WiFi上的DHCP确实分配了相同的网络地址范围192.168.x.y给您的Android设备... - t0mm13b
7个回答

17

“无路由错误”指的是当尝试建立TCP连接时,由于底层协议软件无法找到到达指定目标节点的网络节点到网络节点的路由,所以连接失败。

解决方法在某种程度上依赖于操作系统,但主要需要设置路由表,以便从您尝试连接的设备能够找出如何到达您想要连接的设备。

通常情况下,您会指定一个网关,当您尝试连接时,连接请求通过网络网关发送,由其他信息技术设备(例如路由器等)解析。

看起来这是一个安卓设备,因此第一件事是确保您具有连接性,无论是WiFi还是蜂窝数据。另外,请确保WiFi或蜂窝数据已打开并正常工作。

您指定的IP地址通常在私有子网中。因此,检查的事项是您尝试连接到的设备是否在与您的设备相同的子网上。

这里有一篇关于子网和路由的文档

用户destenson在2017年5月13日评论中的引用

用户destenson在2017年5月13日的评论中提供了针对安卓和文章中提供的错误消息的其他信息。

由于这是安卓设备,因此您需要查看权限。09-21 01:08:40.457: W/System.err(8536): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)表示该连接被设备策略拒绝。


1
由于这是Android,你需要首先查看的是权限。09-21 01:08:40.457: W/System.err(8536): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)表示设备策略拒绝了连接。 - Dennis Estenson

6
这看起来像是网络问题,而不是Java问题。可能是以下原因之一:
  • 客户端网络无法将数据包路由到服务器
  • 防火墙或数据包过滤器阻止了客户端在4449端口的连接尝试
  • 您使用的IP地址不正确。
("无法到达主机"信息表明这是第一个问题,但是防火墙有时会对不需要的流量提供误导性响应。)
总之,最好寻找有关配置和/或网络和路由的网站。

2

你好,我在我的Mac和Android设备上运行应用程序时遇到了同样的问题。我需要做以下两件事才能使它正常工作:

  1. 关闭Mac防火墙
  2. 启用红外接收器(系统偏好设置>安全性>防火墙>高级)

然后它就可以正常工作了!


这对我有用,但我感到关闭防火墙有点不安。 - EdgeDev

1
关闭移动WiFi,然后再打开。
WifiManager mWifiManager = (WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);

mWifiManager.setWifiEnabled(false);
mWifiManager.setWifiEnabled(true);

并再次尝试创建套接字连接


1
我在开发与Java桌面服务器通信的Android应用程序时遇到了同样的问题,为了解决这个问题,只需断开连接Android手机与PC之间的USB电缆即可。

你的回答甚至与问题不符... USB电缆怎么可能对移动网络构成问题。 - Deepak Ganachari
这不可能是一个解决方案,它不会起作用。 - Mousa Alfhaily
1
非常奇怪,我一直在尝试解决这个问题,但直到早上才找到了解决方法。 - Yawar

0

在您的手机上下载一个ping应用程序,尝试ping服务器IP是否正常... 如果使用Apache,请将本地机器IP放入httpd.conf配置文件中。

# Change this to Listen on specific IP addresses as shown below to 
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 127.0.0.1:80
Listen 192.168.1.30:80  (your IP)

-1

是的..

主机无法访问,就像那样。但是,如果一切正常(配置良好的节点/网络,良好的wifi信号等),您可以使用ping serverIP(从手机)或ping smartphone(从服务器)强制执行该过程。

ping(ICMP数据包)将强制路由器加速新路由(到达主机的方式)...发送大量ping(-n选项),例如:ping google.com -n 1000(1000个连续ping)


在尝试连接(应用程序)的同时进行ping测试...你可以考虑对serverPort进行telnet测试(以确保它已开放)。 - Jose Almeida
一个ping命令可能会填充本地ARP表,但不太可能影响其他任何东西,包括路由表(这些表是静态的或通过像BGP这样的协议进行配置,而不是由设备决定)。而且,由于在同一本地子网上执行ARP只需要几毫秒来获取与IP地址对应的MAC地址,所以你不会加快任何事情的速度。 - Brian White

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接