出力ストリームのソケットにしか書いていない場合は、これはブロックされますか?読み取りだけがブロックできますか?誰かが書き込みがブロックすることができると私に言ったが、私はソケットの読み取りメソッドのためのタイムアウト機能 - Socket.setSoTimeout()
を参照してください。Javaソケット/出力ストリーム書き込み:ブロックしますか?
書き込みがブロックされる可能性はありません。
出力ストリームのソケットにしか書いていない場合は、これはブロックされますか?読み取りだけがブロックできますか?誰かが書き込みがブロックすることができると私に言ったが、私はソケットの読み取りメソッドのためのタイムアウト機能 - Socket.setSoTimeout()
を参照してください。Javaソケット/出力ストリーム書き込み:ブロックしますか?
書き込みがブロックされる可能性はありません。
ソケットの書き込みも、特にTCPソケットの場合はブロックできます。 OSは、ある量の未送信(または送信されたが未確認の)データのみをバッファします。リモートアプリが読み込める速度よりも速く書き込むと、ソケットは最終的にバックアップされ、write
コールはブロックされます。これらのフォローアップの質問に応え
:
だから、このため タイムアウトを設定するための仕組みがありますか?私はバッファーがいっぱいであれば のデータが捨てられるかもしれないと確信しています。または、おそらく バッファ内の古いデータを削除しますか?
java.net.Socketに書き込みタイムアウトを設定するメカニズムはありません。 Socket.setSoTimeout()
メソッドがありますが、accept()
とread()
コールには影響しますが、write()
コールには影響しません。どうやら、NIO、ノンブロッキングモード、セレクタを使用すると、書き込みタイムアウトが発生する可能性がありますが、これは想像以上に有用ではありません。
正しく実装されたTCPスタックは、接続が閉じられていない限り、バッファリングされたデータを破棄しません。しかし、書き込みタイムアウトが発生すると、現在OSレベルのバッファにあるデータが相手側で受信されたかどうかは不明です。もう1つの問題は、最後のwrite
のデータが実際にOSレベルのTCPスタックバッファにどれだけ転送されたかわからないことです。 *のストリームを再同期化するためのアプリケーションレベルのプロトコルがない場合、write
のタイムアウト後に行う唯一の安全な作業は、接続をシャットダウンすることです。
UDPソケットを使用している場合、write()
コールはかなりの時間ブロックされません。しかし、欠点は、ネットワークに問題がある場合や、リモートアプリケーションが追いついていない場合、メッセージがどちらの端末にも通知されずにフロアにドロップされることです。また、メッセージがリモートアプリケーションに順不同で配信されることがあります。これらの問題に対処するのはあなた(開発者)次第です。
*これは理論的には可能ですが、ほとんどのアプリケーションでは、すでに信頼できる(ポイントへの)TCP/IPストリームの上に追加の再同期メカニズムを実装することは意味がありません。そして、それが理にかなっていれば、接続が閉じられた可能性にも対処する必要があります。はとする方が簡単です。
これを実行する唯一の方法は、NIOとセレクタを使用することです。
は、このバグレポートに日/ Oracleのエンジニアからの過去記事を参照してください: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4031100
タイムアウト機能が存在しないという事実は、それがブロックしていないことを示し、それ自体ではありません。戻り値がないことを示す1つの指示:ブロックされない場合、実際に書き込まれたバイト数は返されないのはなぜですか?もう一つの示唆はそれを試してみるだけです。 – EJP