1

単純な Java サーバー、クライアント アプリケーションで少し問題があります。基本的に、トピックはそれをすべて言います: サーバー側で writeUTF を実行すると、実行される 2 回ごとにのみ送信されます。例:

サーバ:

public class Server {

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            ServerSocket server     = new ServerSocket(7777);
            Socket client           = server.accept();
            DataOutputStream out    = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
            DataInputStream in      = new DataInputStream(new BufferedInputStream(client.getInputStream()));
            while(true) {
                for(int i = 0; i < 100; i++) {
                    out.writeUTF("Test" + i);
                    out.flush();
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

クライアント:

public class Client {

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            Socket client           = new Socket("localhost", 7777);
            DataInputStream in      = new DataInputStream(new BufferedInputStream(client.getInputStream()));
            DataOutputStream out    = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));

            while(in.readUTF() != null) {
                System.out.println(in.readUTF());
            }
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

コンソールの出力は次のようになります。

テスト1 テスト3 テスト5 テスト7 テスト9 テスト11

この動作の原因は何ですか?

4

4 に答える 4

4

これは、クライアントのデータを破棄しているためです。

をチェックするwhile(in.readUTF() != null)と、毎回ストリームからエントリを読み取って、null でないかどうかを確認します。次に、この値を破棄し、ループ内で新しい値を読み取ります。(値が失われるだけでなく、合計値の数が奇数の場合、while 条件は true と評価されますが、次の呼び出しreadUTF()でループ内で null が返されるというバグがあります。)

これを修正するには、値を変数に読み込み、使用する前にこれをテストする必要があります。次のようにします。

String value;
while((value = in.readUTF()) != null) {
     System.out.println(value);
}

単一の式としての割り当てと無効チェックが気に入らない場合は、代わりにvalue = in.readUTF()最初とすべてのループの最後に割り当てることができますが、個人的には、これはエラーが発生しやすいと思います。

于 2012-07-16T16:20:22.243 に答える
0

このループ

        while(in.readUTF() != null) {
            System.out.println(in.readUTF());
        }

読み取った文字列を 1 秒ごとに破棄します。ファイルの終わりのテスト中に 1 つの文字列を読み取り、それを破棄してから、別の文字列を読み取って出力します。

于 2012-07-16T16:20:42.297 に答える
0

ここでwhileループ評価でデータを消費しています:

  while(in.readUTF() != null) {
      System.out.println(in.readUTF());
  }

代わりにこれを試してください:

  String line;
  while( ((line = in.readUTF()) != null) {
      System.out.println(line);
  }
于 2012-07-16T16:23:43.733 に答える