recv
ノンブロッキング フラグ MSG_NONBLOCK を指定して syscallを使用したいと考えています。ただし、このフラグを使用すると、要求全体が満たされる前に syscall が戻る可能性があります。そう、
- MSG_WAITALL フラグを追加できますか? ノンブロッキングになりますか?
- または、ブロッキング recv を非ブロッキング recv でループに書き直すにはどうすればよいですか
recv
ノンブロッキング フラグ MSG_NONBLOCK を指定して syscallを使用したいと考えています。ただし、このフラグを使用すると、要求全体が満たされる前に syscall が戻る可能性があります。そう、
これは私が同じ問題に対して行ったことですが、これが期待どおりに機能することを確認したいと思います...
ssize_t recv_allOrNothing(int socket_id, void *buffer, size_t buffer_len, bool block = false)
{
if(!block)
{
ssize_t bytes_received = recv(socket_id, buffer, buffer_len, MSG_DONTWAIT | MSG_PEEK);
if (bytes_received == -1)
return -1;
if ((size_t)bytes_received != buffer_len)
return 0;
}
return recv(socket_id, buffer, buffer_len, MSG_WAITALL);
}
編集:
普通の recv() は、要求されたバイト数まで、呼び出し時に tcp バッファにあるものを返します。MSG_DONTWAIT は、ソケットで読み取る準備ができているデータがまったくない場合にブロックを回避するだけです。MSG_WAITALL は、要求されたバイト数全体を読み取ることができるまでブロッキングを要求します。したがって、「すべてかゼロか」の動作は得られません。せいぜい、データが存在しない場合は EAGAIN を取得し、それ以外の場合は完全なメッセージが利用可能になるまでブロックする必要があります。
MSG_PEEK または ioctl() から、FIONREAD (システムがサポートしている場合) を使用して効果的に動作するものを作成できる場合がありますが、recv() フラグを使用するだけで目標を達成する方法がわかりません。