1

msn スイッチボード ソケットからテキストを読み込もうとしています

public String readStream() {
    String temp = null;
    try {
        temp = buffReader.readLine();
        System.out.println("<<< " + temp);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return temp;
}
// this method is called
public void print() {
  while (socket.isConnected()) {
      readStream(); 
  }
}

メッセージが msn で受信された場合、出力は次のようになります ( http://www.hypothetic.org/docs/msn/switchboard/example_session.phpによると) 。

<<< MSG bob@passport.com Bob 143\r\n
MIME-Version: 1.0\r\n
Content-Type: text/plain; charset=UTF-8\r\n
X-MMS-IM-Format: FN=Lucida%20Sans%20Unicode; EF=B; CO=ff0000; CS=0; PF=22\r\n
\r\n
Hello.

私の出力:

<<< MSG myemail@email.com MYNAME 128
<<< MIME-Version: 1.0
<<< Content-Type: text/plain; charset=UTF-8
<<< X-MMS-IM-Format: FN=Arial; EF=; CO=000000; CS=0; PF=00; RL=0;
<<< 

ご覧のとおり、その人が別のメッセージを送信するまで、送信されたメッセージを受信して​​いません。

出力:

<<< MSG myemail@email.com MYNAME 128
<<< MIME-Version: 1.0
<<< Content-Type: text/plain; charset=UTF-8
<<< X-MMS-IM-Format: FN=Arial; EF=; CO=000000; CS=0; PF=00; RL=0;
<<< 
<<< helloMSG myemail@email.com MYNAME 127
<<< MIME-Version: 1.0
<<< Content-Type: text/plain; charset=UTF-8
<<< X-MMS-IM-Format: FN=Arial; EF=; CO=000000; CS=0; PF=00; RL=0;
<<< 

では、メッセージ全体を読むことができるように、これをどのように解決できますか?

4

1 に答える 1

0

問題は、Hello の後にストリームに改行がないことだと思います。したがって、readLine は、次のメッセージの最初の行の最後に来るまで、行の終わりを検出しません。メッセージ全体を取得するには、メッセージの長さに依存して、定義済みのバイト数を読み取る必要があります。いくつかのヒントについては、このサイトをチェックしてください: http://www.hypothetic.org/docs/msn/resources/faq.php#howtoparse

編集:上記のサイトから引用された実装されるロジック最も関連性の高い部分は終わりに近づいています:

サーバーからの新しいデータがソケットを介して到着するたびに、「キャッシュ」として使用される文字列に追加します。データを受信するたびに、キャッシュ パーサー関数も呼び出します。

キャッシュ パーサー関数は、キャッシュ変数を調べて、改行を探します。

見つからない場合、関数は何もせずに戻ります。

見つかった場合は、キャッシュの先頭から改行までのすべてを読み取り、新しい変数に入れます。次に、キャッシュの先頭から改行まで (および改行を含む) のコマンドを削除します。

キャッシュ パーサーは、コマンドの最初の 3 バイトを調べます。

コマンドが通常のコマンドとして認識されると、そのコマンドのハンドラーが呼び出され、ループバックして、キャッシュにさらにコマンドがあるかどうかが確認されます。

これは最も関連性の高い部分です

コマンドがペイロード コマンドとして認識されると、ペイロードの指定された長さが調べられ、それがキャッシュの長さと比較されます。

ペイロード全体がキャッシュ内にあると思われる場合、キャッシュ パーサーは指定された長さまでキャッシュの先頭を取り出し、それをペイロード変数に格納します。次に、ペイロード関数の適切なハンドラーを呼び出し、ループバックして、キャッシュにさらにコマンドがあるかどうかを確認します。

キャッシュの長さがペイロードの指定された長さよりも小さい場合、キャッシュ パーサーはコマンドをキャッシュの先頭に追加して返します。

于 2012-08-16T14:13:07.023 に答える