2011-02-28 11 views
2

Java配列のソケットクラスを使用してバイト配列を送信すると、受信者がデータを受信したことを確認するまで次のコードブロックで書き込み呼び出しを行いますか?データを送信するときにJavaのTCPソケットクラスブロックをブロックします

byte data[] = ...; 
Socket socket = ...; 

socket.getOutputStream().write(data); // blocking ? 

私が尋ねる理由は、私は私がに同じデータを送信するソケットのリストを持っている場合、私は同じ効率、すなわち、できるだけそれを送りたいです、これよりも良い方法があります:

ArrayList<Socket> sockets = ...; 
byte data[] = ...; 

for(int i = 0; i < sockets.size(); i++) 
    sockets.getOutputStream().write(data); 

答えて

5

TCPハンドシェイクがないwrite(2)時に、connect(2)時に起こります。

へのコールwrite(2)の呼び出しは、OS TCP送信バッファがプログラムからより多くのデータを受け入れるのに十分に枯渇するまでブロックします。 (OSが1つの空きバイトに対してwrite(2)オペレーションのブロックを解除したとは想像できません)

唯一の保証は、セッションのウィンドウと内部OSバッファのサイズを足したものです。そのデータのいずれかが他のエンドポイントのアプリケーションに到達したかどうかは、バッファの別のレイヤーです。リモートピアのTCPスタックは、アプリケーションが処理する機会を得る前に受信したデータを確認してバッファに格納しますそれ。

+0

これで、データがスタックのtcpレイヤーに到達するとブロック解除され、クライアントとのtcpハンドシェイクが完了するまで待つ必要はありません。 –

+0

@gamemb、ハンドシェークが完了した後でなければ、あなたのコードは 'write()'コールに進まないでしょう。しかし、そうでなければ、_local_ TCP送信バッファが 'write()'呼び出しを受け入れるのに十分なスペースを解放したときに、コードはブロックを解除します。これは64KBですウィンドウ+ 8キロバイトのバッファサイズで、遠隔ピアが受信し、 'ACK 'されたものよりも前にある。 – sarnold

+0

([TCPウィンドウのスケーリング](http://en.wikipedia.org/wiki/TCP_window_scale_option)を使用すると、64KBウィンドウはちょうど推測に過ぎないことに注意してください)、ウィンドウはメガバイト大きく、ほぼ最大1ギガバイトのデータになる可能性があります。それは、転送中に1ギガバイトのデータを持つ特殊な環境を取るでしょう:) – sarnold

関連する問題