0

私のプログラムは SSLServerSocketを使用して着信接続を待機し、データを受信します。クライアントはサーバーに接続し、一連の 10 バイトのチャンクを に書き込みSocketますOutputStream。チャンクはできるだけ早くサーバーに到着する必要があるため、10 バイトのチャンクごとにOutputStream編集されます (注: ここでは WIFI が使用されます)。flush()

これらのチャンクはサーバーによって読み取られます。OpenJDK 7 を使用して Ubuntu Linux でサーバーを実行すると、正常に動作します。

しかし、Suns Java 7 を使用して Windows でサーバーを実行すると、次の問題が発生し
ます。受信したチャンク間のサーバーでの時間を測定しました。flush()チャンクが書き込まれた後にクライアントが使用しても、サーバーによるデータの受信/読み取りが遅すぎることがあることに気付きました。

例:
最初のチャンクを受信するのに 265 ミリ秒かかります。次の 15 チャンクには、0 ミリ秒から 16 ミリ秒の遅延があります。
その後、172ms 後に次のチャンクが到着します。しかし、次の 10 チャンクも 0ms から 16ms しか必要としません。

そのため、最初にいくつかのバイトが受信され、InputStream によってバッファリングされているようです。その後、ある時点 (たとえば 150 ミリ秒以上後) で、InputStreamの-メソッドreadが何らかのデータを返します。その後、readメソッドはすぐに (0 ミリ秒から 16 ミリ秒まで) いくつかのバイトのデータを返します。そして、それにはまた時間が必要です。新しいバイトが利用可能になるまでバッファを使用し、メソッドがブロックされる
ことを知っています。しかし、- メソッドは可能な限り速くデータを返さないようです。InputStreamreadread

クライアントは常に Android アプリでした。しかし、問題は Linux で実行されているサーバーでは発生しないため (チャンク間の平均は常に 20 ミリ秒)、問題はサーバーまたは JRE にあるはずです。

問題を解決する方法についてのアイデアはありますか? Android アプリでのやり取りはほぼリアルタイムでアニメーションとしてサーバーに表示される必要があるため、クライアントから送信されたチャンクの「流動的な」転送が本当に必要です。しかし、265 ミリ秒の遅延で、これらのアニメーションは動かなくなりました。

4

2 に答える 2

2

InputStream はデータをバッファリングします

いいえ、そうではありません。BufferedInputStream を使用しない限り、InputStream バッファリングはありません。送信は、カーネル内の TCP Nagleアルゴリズムによって結合されています。送信側で Socket.setTcpNoDelay(true) を呼び出します。

SSL 経由で 10 バイトのチャンクを送信するのは非常に非効率的であることに注意してください。SSL 自体には約 44 バイトのレコード オーバーヘッドがあり、TCP にはさらに 20 バイトあるため、4 倍近くのデータ爆発があります。可能であれば、平文を使用してください。

于 2012-10-05T22:54:01.903 に答える
2

なぜ問題は InputStream の read メソッドだと思いますか? 実際にネットワーク トラフィックを監視するためにパケット スニファーをセットアップしましたか? Java はバッファリングを行っていません。ネットワーク スタックはバッファリングを行っています。ソケット設定の一部を微調整することで、それに影響を与えることができる場合とできない場合があります。

于 2012-10-05T15:27:05.547 に答える