1

Java ソケット コードに少し問題があります。直接(!)ワイヤレス接続を介して、PCのJavaマルチスレッドソケットサーバーにデータを送信するAndroidクライアントアプリケーションを作成しています。正常に動作しますが、今では非常に電力を消費するため、モバイル アプリケーション用に改善したいと考えています。コード内の 2 つの特別な行を削除すると、モバイル デバイス (htc one x) の CPU 使用率はまったく問題ありませんが、接続の ping レートが高いなどのようです...

クライアントデータを受け取るサーバーコードスニペットは次のとおりです。

while(true)
  {
    try {
                   ....
            Object obj = in.readObject();
            if(obj != null) {
                Class clazz = obj.getClass();
                String className = clazz.getName();
                if(className.equals("java.lang.String")) {
                    String cmd = (String)obj;
                    if(cmd.equals("dc")) {
                        System.out.println("Client "+id+" disconnected!");
                        Server.connectedClients[id-1] = false;
                        break;
                    }
                    if(cmd.substring(0,1).equals("!")) {
                        robot.keyRelease(PlayerEnum.getKey(cmd,id));
                    }
                    else {
                        robot.keyPress(PlayerEnum.getKey(cmd,id));
                    }

                }
            }

    } catch ....

ここでは、while ループでデータを送信するクライアント部分を示します。

private void networking() {
    try {
        if(client != null) {
            ....
                out.writeObject(sendQueue.poll());

            ....
        }
    } catch ....

この理由を書くと、whileループが実行されるたびにデータを送信します.. sendQueueが空の場合、nullの「オブジェクト」が送信されます。これにより、ネットワーク トラフィックが「高く」なり、CPU 使用率が「高く」なります。BUT: すべての送信コメントはほぼ即座に受信されます。

コードを次のように変更すると:

while(true)
...
if(sendQueue.peek() != null) {
    out.writeObject(sendQueue.poll());
}
...

CPUの使用率はまったく問題ありませんが、ラグが発生しています..コマンドが十分に速く到着しません..私が言ったように、(そのnullオブジェクトで)データを送信している場合、(CPUの使用率を除いて)正常に動作します実行。しかし、これは非常にラフなコーディング スタイルであると確信しています。ヒントはありますか?

私は何を間違っていますか??


ご協力いただきありがとうございます!

よろしくお願いします。

4

3 に答える 3

1

コードの CPU 集中型バージョンが、出力ストリームをnull値でフラッディングしています。それらは送信されるデータとしてカウントされます。サーバーはそれらを明示的に無視しますが、最終的には有用なデータも強制的に通過させるのに役立ちます.

を使用して変更したコードpeekはより合理的です。flushの後 に呼び出すのが良い形式writeObjectです。そうしないと、書き込まれたオブジェクトが出力バッファーにスタックし、さらにアイテムが来るのを待つ可能性があります。バッファリングは、多くのオブジェクトが一緒に送信される場合のパフォーマンスの最適化です。バッファリングを行わないストリーム クラスでは、フラッシュは必要ありません。

さらに良い:

Object item = sendQueue.poll();
if (item != null) {
    out.writeObject(item);
    out.flush();  // maybe not needed, depending on the class of your stream 
}

これはわずかに高速です。いずれにせよすぐにpeek実行するつもりなら、評価しても意味がありません。poll

さらに、socket.setTcpNoDelay(true)ソケットをに渡す前にソケットを呼び出しますSocketOutputStream(それが出力ストリームの作成方法であると仮定します)。これにより、ネットワーク帯域幅を節約するための最良の決定であるとは限らないNagle アルゴリズムが無効になりますが、TCP 送受信バッファの調整以外に、クライアントとサーバーが正しく動作することを確認する簡単な方法です。サーバーに直接接続している場合は、Nagle アルゴリズムを無効にすることについてまったく心配しません。

于 2012-06-16T21:57:42.747 に答える
0

追記として、ネットワークの使用を含むアプリの最適化を行うのに役立つAndroid用のAROツールを確認することをお勧めします。http://developer.att.com/developer/legalAgreementPage.jsp?passedItemId=9700312

于 2012-06-26T14:22:24.513 に答える
0

null を返すのではなく、poll() がブロックされるように、ブロッキング キューを使用する必要があります。ヌルを送信しても意味がありません。全員の時間、帯域幅、およびお金が無駄になるだけです。

于 2012-06-17T21:40:54.490 に答える