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 に答える