0

ソケットからデータを受信する関数があります。追加のスレッドを作成せずに 5 秒が経過したときに関数を停止する必要があります。私のコード:

void TestReceive()
{
 //how to stop code below when 5 second passed&
 size_t received = 0;
 while (received < 4)
 {
  ssize_t r = read(fd, buffer, 4);
  if (r <= 0) break;
  received += r;
 }
}
4

4 に答える 4

2

select() を使用します。これは、何かが読み取れるようになるまで、または以下のように timeval で指定された時間だけブロックされます。

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

select() は読み取りも書き込みもせず、一連の記述子 (readfds、writefds、および/または exceptfds) を対象としており、次のいずれかが発生するまで待機/ブロックします。

  • 読み取り可能な記述子がある
  • 書き込み可能な記述子がある
  • 記述子の 1 つに例外があり、閉じられたようです
  • タイムアウトが指定されている場合、構成された時間が経過したとき

単純に 5 秒間「待機」(スリープ) してから読み取る必要がある場合は、( usleep()Linux では) 5 秒間スリープしてから、ソケット オプションを設定するか、select() を呼び出して非ブロッキング読み取りを実行できます。最小タイムアウトを確認し、読み取るものがあるかどうかを確認します。

ここに関連する質問があります。C++ select() 関数は Unix OS でどのように機能しますか?

于 2012-05-30T13:03:11.537 に答える
1

@Bradyが示唆したように、select()は機能します

ソケットオプションを設定することもできます setsockopt(s, SOL_SOCKET, SO_RCVTIMEO ...

于 2012-05-30T13:08:56.617 に答える
0

次のアプローチをお勧めします。

  • startTime などの変数に現在の時間を測定します。
  • ループ
  • タイムアウトを使用してソケットから読み取ります(選択)。タイムアウトをstartTime + 5 秒にします - 今
  • タイムアウトが一致するまで繰り返します (または、タイムアウトが適用するには小さすぎます)。

このアプローチでは、別のスレッドの代わりにタイムアウトを使用します

于 2012-05-30T13:45:05.633 に答える
0

ループが始まる前に現在の時間を記録します。反復ごとに - 5 秒が経過したかどうかを確認し、経過した場合は中断します。

于 2012-05-30T13:06:06.817 に答える