1. ホーム
  2. c

[解決済み] Linux: ソケットからの読み込みや読み込みがタイムアウトすることはありますか?

2022-08-30 10:25:34

質問

タイムアウトしたソケットからデータを読み込むにはどうしたらよいでしょうか。 select, pselect, pollにタイムアウトフィールドがあるのは知っていますが、これらを使用するとtcp reno stackの"tcp fast-path"が無効になってしまいます。

私が持っている唯一の考えは、ループで recv(fd, ..., MSG_DONTWAIT) を使用することです。

どのように解決するのですか?

あなたは setsockopt 関数を使用して、受信操作のタイムアウトを設定することができます。

SO_RCVTIMEO

入力の最大時間を指定するタイムアウト値を設定します。 入力関数が完了するまでの最大時間 関数が完了するまで待機する時間の最大値を指定します。これは を含むtimeval構造体を受け取ります。 秒数およびマイクロ秒数 を指定する。 入力操作が完了するまで待つ時間の制限を指定する。 を受け取る。受信動作がこの時間 受信動作がこの時間だけブロックされ 受信動作が追加データを受信せずにこの時間ブロックされた場合,その動作は 部分的なカウントまたは errno で戻る。 を[EAGAIN]または[EWOULDBLOCK]に設定し、データを受信しない場合は を設定する。このオプションのデフォルトはゼロである。 このオプションのデフォルトは0であり,これは受信動作がタイムアウトしないことを示す。 受信動作はタイムアウトしてはならない。 このオプションは、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);

報告されている を呼び出す前に行う必要があります。 bind . 私は実験によって、この処理は bind の前でも後でもできることを実験で確認しました。