3

我在我的 android 应用程序中使用 TCP 连接。连接在专用线程中运行。

我的代码:

class ReceiverThread extends Thread {
Handler handler;

ReceiverThread(Handler h) {
    handler = h;
}

@Override
public void run() {


    try {
            socketTCP = new Socket((SERVERIP), SERVERPORT);
            in = new BufferedReader(new InputStreamReader(
                    socketTCP.getInputStream()));
            socketTCP.setSoTimeout(20000);

            while (TCPRunning) {

                String strTcp = in.readLine().toString();
                i++;
                Message msg = handler.obtainMessage();
                Bundle b = new Bundle();
                b.putString("getStr", strTcp + "\n");
                msg.setData(b);
                handler.sendMessage(msg);

            }

        } catch (UnknownHostException e) {
            Log.v("TcpClient", "Unknown host");
            try {
                socketTCP.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();

        } catch (SocketException e) {
            // Erreur TimeOut
            Message msg = handler.obtainMessage();
            Bundle b = new Bundle();
            b.putString("getStr", "Error");
            msg.setData(b);
            handler.sendMessage(msg);
            e.printStackTrace();

        } catch (IOException e) {
            if (socketTCP != null) {
                try {
                    socketTCP.close();
                    socketTCP = null;
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }

        } finally {
            try {
                i = 0;
                if (in != null) {
                    in.close();
                }
                if (socketTCP != null) {
                    socketTCP.close();
                    socketTCP = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

然后,当我启动我的应用程序时,我将 android 设备连接到另一台设备的 wifi;它运作良好:我接收到另一台设备发送的数据。当我停止连接并重新启动时(几秒钟后)它可以工作。

但是当我等待 2 或 3 分钟时,连接变得不可能:

我得到以下异常:

02-25 10:40:32.638: W/System.err(4384): java.net.ConnectException: failed to connect to /192.168.56.1 (port 50000): connect failed: EHOSTUNREACH (No route to host)
02-25 10:40:32.648: W/System.err(4384):     at libcore.io.IoBridge.connect(IoBridge.java:114)
02-25 10:40:32.648: W/System.err(4384):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
02-25 10:40:32.648: W/System.err(4384):     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
02-25 10:40:32.648: W/System.err(4384):     at java.net.Socket.startupSocket(Socket.java:566)
02-25 10:40:32.648: W/System.err(4384):     at java.net.Socket.tryAllAddresses(Socket.java:127)
02-25 10:40:32.658: W/System.err(4384):     at java.net.Socket.<init>(Socket.java:177)
02-25 10:40:32.658: W/System.err(4384):     at java.net.Socket.<init>(Socket.java:149)
02-25 10:40:32.658: W/System.err(4384):     at nke.service.wificonnection.ThreadWifi$ReceiverThread.run(ThreadWifi.java:163)
02-25 10:40:32.658: W/System.err(4384): Caused by: libcore.io.ErrnoException: connect failed: EHOSTUNREACH (No route to host)
02-25 10:40:32.658: W/System.err(4384):     at libcore.io.Posix.connect(Native Method)
02-25 10:40:32.658: W/System.err(4384):     at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)
02-25 10:40:32.668: W/System.err(4384):     at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
02-25 10:40:32.668: W/System.err(4384):     at libcore.io.IoBridge.connect(IoBridge.java:112)
02-25 10:40:32.668: W/System.err(4384):     ... 7 more

如果我想再次使用连接,我必须刷新wifi连接(在Android的参数中,停止并重新启动wifi并连接到设备的wifi)。

可能是什么问题呢?错误后关闭套接字时是否有问题?

4

1 回答 1

1

EHOSTUNREACH错误意味着目的地没有响应。

基本上有几种方法可以发生这种情况:

  • 数据链路层已消失(即 WiFi 已掉线)
  • 路由表已更改,数据包不再到达所需目的地
  • 防火墙导致数据包被丢弃。
  • 远程主机没有响应连接请求(端口可能已关闭但已过滤)

您可以尝试连接到目标上的其他端口。如果当您的应用程序不起作用时这有效,则接收(服务器)应用程序不再侦听。如果所有可访问的端口突然都无法访问,那么这是您的 WiFi 或路由表或一般防火墙问题。

您仍然可以拥有到该主机的有效 IP 路由,但如果出于安全原因过滤连接请求,您将收到此错误。过滤对于封闭的端口很常见,因此设备的端口扫描除了一个空洞之外什么都不会显示,就好像那个地址没有任何东西一样。我找不到任何明确的参考资料表明 Android 会这样做,但似乎很有可能。

于 2014-11-27T17:00:14.833 回答