GNU/Linux >> Linux の 問題 >  >> Linux

読み取り関数呼び出しでタイムアウトを実装するには?

ソケットがノンブロッキング モードで動作するように設定すると、read を呼び出すたびに、現在使用可能なデータ (存在する場合) のみが読み取られます。したがって、これは事実上即時タイムアウトと同じです。

次のような関数を使用して、ソケットにノンブロッキング モードを設定できます:

int setnonblock(int sock) {
   int flags;
   flags = fcntl(sock, F_GETFL, 0);
   if (-1 == flags)
      return -1;
   return fcntl(sock, F_SETFL, flags | O_NONBLOCK);
}

(ノンブロッキング ソケットからの読み取りの詳細については、read を参照してください。 マンページ)


OSが何であるかはわかりませんが、Linuxで実行している場合は、選択呼び出しを使用できます。ファイル記述子に読み取るものがあれば返されます。または、読み取るものが何もない場合にタイムアウトするように設定できます。戻りコードはどれかを示します。


select() の代替として 、シリアルポート(端末)の特定のケースでは、 tcsetattr() を使用できます ファイル記述子を非標準モードにし、読み取りタイムアウトを設定します。

これを行うには、ICANON の設定を解除します フラグを設定し、VTIME を設定します 制御文字:

struct termios termios;

tcgetattr(filedesc, &termios);
termios.c_lflag &= ~ICANON; /* Set non-canonical mode */
termios.c_cc[VTIME] = 100; /* Set timeout of 10.0 seconds */
tcsetattr(filedesc, TCSANOW, &termios);

VTIME に注意してください は 10 分の 1 秒単位で測定され、それに使用される型は通常 unsigned char です。 、つまり、最大タイムアウトは 25.5 秒です。


select() は 5 つのパラメーターを受け取ります。最初に最も高いファイル記述子 + 1、次に読み取り用の fd_set、書き込み用、および例外用の 1 つです。最後のパラメーターは、タイムアウトに使用される構造体 timeval です。エラーの場合は -1、タイムアウトの場合は 0、または設定されているセット内のファイル記述子の数を返します。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>

int main(void)
{
  fd_set set;
  struct timeval timeout;
  int rv;
  char buff[100];
  int len = 100;
  int filedesc = open( "dev/ttyS0", O_RDWR );

  FD_ZERO(&set); /* clear the set */
  FD_SET(filedesc, &set); /* add our file descriptor to the set */

  timeout.tv_sec = 0;
  timeout.tv_usec = 10000;

  rv = select(filedesc + 1, &set, NULL, NULL, &timeout);
  if(rv == -1)
    perror("select"); /* an error accured */
  else if(rv == 0)
    printf("timeout"); /* a timeout occured */
  else
    read( filedesc, buff, len ); /* there was data to read */
  close(filedesc);
}

Linux
  1. 未定義の関数apc_fetch()の呼び出しを修正する方法–PHPの致命的なエラー[解決済み]

  2. Pkex​​ec – Pkexecポリシーを作成するときにAuth_admin_keepのカスタムタイムアウトを設定するにはどうすればよいですか?

  3. Bittornadoトラッカーを設定する方法は?

  1. Nginxリバースプロキシを設定する方法

  2. Ubuntu 20.04でGrubタイムアウトを変更する方法は?

  3. C++ で C 関数を呼び出す方法、C で C++ 関数を呼び出す方法 (C と C++ の混合)

  1. Linux環境変数:LinuxVPSでの読み取りと設定の方法

  2. SSHトンネリングを設定する方法

  3. Awk内のBashスクリプトでBash関数を呼び出す方法は?