web-dev-qa-db-ja.com

recvfrom()関数を非ブロッキングにする

私はUDPサーバー/クライアントアプリケーションに取り組んでいます。

クライアントのいずれかがダウンしているかどうかを確認するために、サーバーはハンドシェイクメッセージをクライアントに送信します。次に、サーバーは、クライアントがアクティブであることを確認するために、クライアントの応答がデータを送信するのを待ちます。このため、サーバーは、クライアントが応答しない限り、recvfrom()の呼び出しをブロックしますが、クライアントがダウンしている場合、サーバーはrecvfrom()の呼び出しを無限にブロックします。

このような機能をサーバーに実装して、recvfrom()の呼び出しを特定の時間(たとえば2秒)待機するようにします。 2秒以内にクライアントからデータが受信されなかった場合、クライアントは停止していると見なされ、recvfrom()が返されます。

それを行う方法はありますか?インターネットを検索しましたが、データを受信しなかったときにすぐに戻る_MSG_DONTWAIT_フラグを設定するなどの解決策を見つけましたが、私の場合、recvfrom()をすぐに返したくないのですが、特定の期間データを待ちます時間の経過とともに、その特定の期間にデータが受信されなかった場合、recvfrom()関数が返されます。

14
Ayse

最も簡単な方法は、setsockopt()を使用して、問題のソケットの受信タイムアウトを設定することです。

これには_SO_RCVTIMEO_が使用されます。

recvfrom()に渡されたソケットにタイムアウトが設定されている場合、データが受信されていなければ、関数はこのタイムアウト後に戻ります。

たとえば、10 usecの読み取りタイムアウトを設定するには(必要に応じてsetsockopt()からの戻り値にエラーチェックを追加します):

_#include <sys/types.h> 
#include <sys/socket.h>

...

struct timeval read_timeout;
read_timeout.tv_sec = 0;
read_timeout.tv_usec = 10;
setsockopt(socketfd, SOL_SOCKET, SO_RCVTIMEO, &read_timeout, sizeof read_timeout);
_

詳細については Windowsの場合はこちらをご覧くださいLinuxの場合はこちらをご覧ください および/または こちら(POSIX)

13
alk