1

そのため、C++ でプログラムされた Windows の TCP サーバーと、Java の Android 4.0.4 のクライアントがあります。

Android では、次のように接続します。

public boolean sendConnectRequest()
{
    while (isSocketConnected == false)
    {
        try {
            if(comSocket == null)
            comSocket = new Socket("192.168.0.1",1531);
            isSocketConnected = comSocket.isConnected();
            if (isSocketConnected) {
                out = comSocket.getOutputStream();
                in = comSocket.getInputStream(); 
            }
            else
                comSocket.close();
        } 
        catch (IOException ex)
        {
            Log.e("TCP Error", ex.getLocalizedMessage());
        }
    }
return true;
}

通常、サーバーへの最初の接続では、このコードに問題はありません。

サーバーから切断すると、次のように呼び出します。

public void closeConnection() {
    if (comSocket != null)
    {
        try {
            comSocket.close();
            isSocketConnected = false;
            if (out != null)
                out.close();
            if (in != null)
                out.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

ここで問題が発生しました... スマートフォンのホームボタンを押すと、プログラムが一時停止します。プログラムを再度開始すると、アクティビティで再開機能が呼び出され、再接続に向けたプロセスが開始されます。接続が試行され、エラーは発生しません。ただし、Windows サーバーは接続を記録しません。Windows では、私はまだブロックされていることを知っています:

SOCKET connectionSocket = accept(tcpNetworkData->socket, (struct sockaddr*)&from, &fromlen);

これは正常だと思います。Android 側でデバッグ モードにすると、次の行からすぐに戻ることに気付きました。これは、接続が確立されたことを示しているはずです。

これまでのところ私に従っている場合...サーバーをシャットダウンすると、クライアントは接続を閉じて新しい接続を開くことでリセットされます。今回は、comSocket = new Socket("192.168.0.1",1531) がブロックされず、実行が続行されます。これは明らかに間違っています。リソース解放の問題だと思いますが、なぜですか? Winsock を使用すると、次のコード行でこの問題を解決できます。

int so_reuseaddr = TRUE;
setsockopt(networkData->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&so_reuseaddr,sizeof(so_reuseaddr));

Android でも同様のことができますか、それともしなければなりませんか? ご協力ありがとうございました!

4

2 に答える 2

3

javadocによると、コンストラクターを呼び出すと接続が確立されます。

  Socket(InetAddress address, int port)
      Creates a stream socket and connects it to the specified port number at the specified IP address.

ホームボタンを押すと、アプリはバックグラウンドに入りますが、すぐには強制終了されないためcomSocket、アプリケーションに戻ったときに null ではない可能性があります。その場合、コンストラクターを再度呼び出していないため、サーバーに再接続していません。あなたがすべきことは

if(comSocket == null){
        comSocket = new Socket("192.168.0.1",1531);
}else{
     comSocket.connect(new InetSocketAddress("192.168.0.1",1531));
}

(そして、中括弧を配置してください:-) )

于 2013-03-13T21:20:07.307 に答える
1

isConnected() メソッドは、リモート側がいつ接続を閉じたかを検出する信頼性が高くないことに注意してください (ここに例を示します)

関連する入力/出力ストリームで読み取りまたは書き込みを行うことにより、これを把握する必要があります。

クライアントがサーバーに接続できなくなるとすぐにtrue を返す PrintWriter.checkError() を使用してみてください。

于 2013-03-13T21:23:04.547 に答える