// WINDOWS のバインド操作後も機能します
DWORD timeout = timeout_in_seconds * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
setsockopt 関数を使用して、受信操作のタイムアウトを設定できます:
<ブロック引用>SO_RCVTIMEO
入力関数が完了するまで待機する最大時間を指定するタイムアウト値を設定します。入力操作が完了するまで待機する時間の制限を指定する秒数とマイクロ秒数を持つ timeval 構造体を受け入れます。追加のデータを受信せずに受信操作がこの時間ブロックされた場合、データが受信されない場合は、部分的なカウントまたはエラーが [EAGAIN] または [EWOULDBLOCK] に設定されて返されます。このオプションのデフォルトはゼロで、受信操作がタイムアウトしないことを示します。このオプションは timeval 構造を取ります。すべての実装でこのオプションを設定できるわけではないことに注意してください。
// LINUX
struct timeval tv;
tv.tv_sec = timeout_in_seconds;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
// WINDOWS
DWORD timeout = timeout_in_seconds * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);
// MAC OS X (identical to Linux)
struct timeval tv;
tv.tv_sec = timeout_in_seconds;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
報告によると、Windows では bind
を呼び出す前にこれを行う必要があります。 . bind
の前後どちらでもできることを実験で確認しました Linux および OS X で。
SIGALRM
のハンドラをインストールする 、次に alarm()
を使用します または ualarm()
通常のブロッキング recv()
の前に .アラームが鳴ったら recv()
errno
でエラーを返します EINTR
に設定 .
recv
にタイムアウトを追加する簡単なコードを次に示します。 poll
を使用した関数 C:
struct pollfd fd;
int ret;
fd.fd = mySocket; // your socket handler
fd.events = POLLIN;
ret = poll(&fd, 1, 1000); // 1 second for timeout
switch (ret) {
case -1:
// Error
break;
case 0:
// Timeout
break;
default:
recv(mySocket,buf,sizeof(buf), 0); // get your data
break;
}