GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie implementiert man ein Timeout im Lesefunktionsaufruf?

Wenn Sie den Socket so einstellen, dass er im nicht blockierenden Modus betrieben wird, liest jeder Aufruf von read nur die aktuell verfügbaren Daten (falls vorhanden). Dies entspricht also effektiv einem sofortigen Timeout.

Sie können den nicht blockierenden Modus für einen Socket mit einer Funktion wie dieser einstellen:

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);
}

(Weitere Informationen zum Lesen aus nicht blockierenden Sockets finden Sie im read Manpage)


Sie sagen nicht, was das Betriebssystem ist, aber wenn Sie unter Linux laufen, könnten Sie den select-Aufruf verwenden. Es kehrt zurück, wenn im Dateideskriptor etwas zu lesen ist, oder Sie können es so einrichten, dass es abläuft, wenn nichts zu lesen ist. Der Rückgabecode gibt an, welche.


Alternativ zu select() , für den speziellen Fall einer seriellen Schnittstelle (Terminal) können Sie tcsetattr() verwenden um den Dateideskriptor in den nicht-kanonischen Modus zu versetzen, mit einem Lese-Timeout.

Deaktivieren Sie dazu die ICANON Flag und setzen Sie VTIME Steuerzeichen:

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);

Beachten Sie VTIME in Zehntelsekunden gemessen wird und dass der dafür verwendete Typ typischerweise ein unsigned char ist , was bedeutet, dass das maximale Timeout 25,5 Sekunden beträgt.


select() nimmt 5 Parameter, zuerst den höchsten Dateideskriptor + 1, dann ein fd_set zum Lesen, eines zum Schreiben und eines für Ausnahmen. Der letzte Parameter ist ein Struktur-Zeitwert, der für die Zeitüberschreitung verwendet wird. Es gibt -1 bei einem Fehler, 0 bei Zeitüberschreitung oder die Anzahl der Dateideskriptoren in den gesetzten Sätzen zurück.

#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. So richten Sie einen Nginx-Reverse-Proxy ein

  2. Linux-Umgebungsvariablen:Lesen und Festlegen auf einem Linux-VPS

  3. So beheben Sie den Aufruf der undefinierten Funktion apc_fetch() – PHP Fatal Error [Gelöst]

  4. Wie richte ich einen Bittornado-Tracker ein?

  5. Aufrufen von C-Funktionen in C++, C++-Funktionen in C (C und C++ mischen)

So richten Sie WordPress auf einem Raspberry Pi ein

So richten Sie einen Cron-Job unter Linux ein

So lesen Sie eine Datei Zeile für Zeile in Bash

So legen Sie den Hostnamen unter Linux fest oder ändern ihn

So installieren und konfigurieren Sie SeedDMS

Wie kann man das Timeout in Putty erhöhen?