recv を初めて呼び出した後、読み取りバッファーが空かどうかを知るにはどうすればよいですか?
初めて (クライアントを受け入れた後) でも、クライアント接続が失われた場合、recv がブロックされて失敗する可能性があります。次のいずれかを行う必要があります。
select
or (BSDソケット)またはOS固有の同等のものを使用poll
すると、特定のソケット記述子で利用可能なデータがあるかどうかがわかります(例外条件、およびより多くの出力を書き込むことができるバッファスペース)
- ソケットをノンブロッキングに設定できます。これにより、
recv
すぐに利用できるものだけが返されます (おそらく何も返されません) 。
- データをブロックする余裕があるスレッドを作成できます。
recv
他のスレッドが、続行することに関心のある他の作業を行っていることを知っています。
recv_buffer に読み取ったバイト数を知るにはどうすればよいですか? 受信したメッセージに null バイトが含まれている可能性があるため、strlen を使用できません。
recv()
読み取ったバイト数を返すか、エラーの場合は -1 を返します。
TCP はバイト ストリームプロトコルであることに注意してください。つまり、TCPからバイトを正しい順序で読み書きできることのみが保証されますが、メッセージ境界が保持されることは保証されません。したがって、送信者がソケットに大きな単一の書き込みを行ったとしても、途中で断片化されていくつかの小さなブロックに到着するか、いくつかの小さなsend()
/が統合されて 1 つの/write()
によって取得される可能性があります。recv()
read()
そのため、recv
必要なすべてのデータ (つまり、処理できる完全な論理メッセージ) を取得するか、エラーが発生するまで、呼び出しをループするようにしてください。クライアントから後続の の一部/すべてを取得する準備ができている/処理できる必要がありsend
ます (両側から完全なメッセージを取得した後にのみ送信するプロトコルがなく、メッセージの長さを持つヘッダーを使用していない場合) . メッセージ ヘッダー (長さを含む) の recvs を実行してから本文を実行すると、より多くの への呼び出しが発生しrecv()
、パフォーマンスに悪影響を及ぼす可能性があることに注意してください。
これらの信頼性の問題は、しばしば無視されます。単一のホスト、信頼性が高く高速な LAN、関係するルーターとスイッチの数が少なく、メッセージが少ないか非同時の場合、それらが現れる頻度は低くなります。その後、負荷がかかったり、より複雑なネットワーク上で壊れたりする可能性があります。