2

次のコードを使用して、ネットワークソケットからデータを読み取ろうとしています-

Socket s = new Socket(address, 502);
response = new byte[1024];
InputStream is = s.getInputStream();
int count = is.read(response, 0, 100);

データ量は多くありません。全部で 16 バイトです。ただし、read() ステートメントは、一度にすべてのデータを読み取るわけではありません。バッファには 8 バイトのデータしか読み込まれません。

データを読み取るには、このように read() を複数回呼び出す必要があります-

Socket s = new Socket(address, 502);
response = new byte[1024];
InputStream is = s.getInputStream();
int count = is.read(response, 0, 100);
count += is.read(response, count, 100-count);

なぜこうなった?read() が一度にストリーム全体を読み取らないのはなぜですか?

データは順次到着していませんのでご注意ください。Thread.sleep(2000) を呼び出してデータを読み取る前に 2 秒間待機すると、動作は変わりません。

4

3 に答える 3

7

read() が一度にストリーム全体を読み取らないのはなぜですか?

そうするように指定されていないからです。Javadoc を参照してください。少なくとも 1 バイトが使用可能になるまでブロックし、1 から指定された長さまでの数値を返します。

これは、データが必ずしも一度に到着するとは限らないためです。TCP がデータを送受信する方法を制御することはできません。バイトストリームとして扱う必要があります。

于 2012-08-23T10:59:44.770 に答える
1

データが到着するまでブロックすることは理解しています。「それは、データが必ずしも一度に到着するとは限らないためです。」私の質問はなぜですか。

ネットワークは通常、データをパケットに分割するため、必ずしもすべてのデータが一度に到着するとは限りません。IP はパケット交換プロトコルです。

TCP は 8 バイトのブロックを送信しますか?

おそらく、しかしおそらくそうではありません。パケット サイズは、データが通過したネットワークによって異なりますが、一般的なインターネット パケット サイズは約 1500 バイトです。

一度に 8 バイトを受信して​​いる場合は、データが異常に小さいパケット サイズのネットワークを介して送信されているか、または (可能性が高い) 送信者が一度に 8 バイトのデータを送信しています。2番目の説明は、他のコメントの内容と多かれ少なかれ一致しています。

また、明示的に 100 を指定したので、バッファ内のデータよりもはるかに大きい数を、少なくとも 100 バイトまで読み取ろうとするべきではありませんか?

うーん、ダメ。そのように動作するように指定されておらず、そのようには動作しません。仕様に従ってコードを記述する必要があります。


これは、デバイスが「ポーリング」される方法と関係がある可能性があります。しかし、デバイスの仕様を見なければ (またはそれが何であるかを正確に知らなくても)、これは推測にすぎません.

于 2012-08-23T11:18:20.393 に答える
0

もしかしたら、あなたが読んだのではなく送信者のせいで、データが徐々に届いているのかもしれません。

送信者は、BufferedOutputStream (中央) を使用して、送信前に大きなチャンクを作成する必要があります (必要な場合にのみフラッシュを使用します)。

于 2012-08-23T12:09:43.033 に答える