Recvfrom()-Funktion nicht blockierend machen

Lesezeit: 3 Minuten

Benutzer-Avatar
Ayse

Ich arbeite an einer UDP-Server/Client-Anwendung.

Um herauszufinden, ob einer der Clients ausgefallen ist, sendet der Server eine Handshake-Nachricht an den Client. Dann wartet der Server auf die Antwort des Clients, um einige Daten zu senden, um sicherzustellen, dass der Client aktiv ist. Dazu blockiert der Server den Anruf recvfrom() es sei denn, der Client antwortet zurück, aber wenn der Client ausgefallen ist, blockiert der Server unendlich viele Anrufe recvfrom().

Ich möchte eine solche Funktionalität auf meinem Server implementieren, damit er auf den Aufruf wartet recvfrom() für eine bestimmte Zeit (z. B. 2 Sekunden). Wenn innerhalb von 2 Sekunden keine Daten vom Client empfangen wurden, gilt der Client als tot und recvfrom() kehrt zurück.

Gibt es eine Möglichkeit, dies zu tun? Ich habe im Internet gesucht, aber Lösungen wie Einstellungen gefunden MSG_DONTWAIT Flag, das sofort zurückkehrt, wenn keine Daten empfangen werden, aber in meinem Fall möchte ich nicht recvfrom() sofort zurückzukehren, aber für eine bestimmte Zeitdauer auf Daten zu warten, und wenn für diese bestimmte Zeitdauer keine Daten empfangen werden, die recvfrom() Funktion sollte zurückkehren.

  • Ok, Sie möchten einen zuverlässigen Dienst implementieren. kannst du einstellen recvfrom()-Funktion im Sperrmodus mit fcntl()- oder ioctl()-Funktion. Lesen Sie auch diese Implementierung des zuverlässigen UDP-Datendienstes

    – Grijesh Chauhan

    11. April 2013 um 5:46 Uhr


  • Kasse c – Timeout für winsock recvfrom festlegen – Stack Overflow

    – Koushik Shetty

    11. April 2013 um 5:49 Uhr

  • Auch Kasse .es gibt Ihnen eine klare Erklärung in WSARecv() (hat Sperrregeln für die Funktion).

    – Koushik Shetty

    11. April 2013 um 5:52 Uhr


  • @GrijeshChauhan Es ist ioctlsocket für Windows. Etwas lahm und nicht-Unix-artig, aber Sockets werden nicht als normale Dateien behandelt …

    – autistisch

    11. April 2013 um 5:57 Uhr

  • Was ist mit der Verwendung select() nachdem Sie den zu testenden Kunden angeschrieben haben. select() übernimmt eine optionale Auszeit.

    – alk

    11. April 2013 um 6:17 Uhr


Benutzer-Avatar
alk

Der einfachste Weg wäre die Verwendung setsockopt() um ein Empfangs-Timeout für den betreffenden Socket festzulegen.

SO_RCVTIMEO wird dafür verwendet.

Wenn ein Timeout für einen Socket festgelegt wurde, an den übergeben wird recvfrom()kehrt die Funktion nach diesem Timeout zurück, wenn keine Daten empfangen wurden.

Um beispielsweise ein Lese-Timeout von 10 μs festzulegen (fügen Sie eine Fehlerprüfung für den von zurückgegebenen Wert hinzu setsockopt() wie nötig):

#include <sys/types.h> 
#include <sys/socket.h>

...

struct timeval read_timeout;
read_timeout.tv_sec = 0;
read_timeout.tv_usec = 10;
setsockopt(socketfd, SOL_SOCKET, SO_RCVTIMEO, &read_timeout, sizeof read_timeout);

Für Details unter Windows finden Sie hierund unter Linux siehe hier und/oder hier (POSIX).

  • oder verwenden select() warten, bis der Socket innerhalb eines Timeouts in einen lesbaren Zustand übergeht, dann Aufruf recvfrom() nur wenn der Socket tatsächlich lesbar ist, was anzeigt, dass Daten zum Lesen verfügbar sind.

    – Rémy Lebeau

    11. April 2013 um 19:46 Uhr


  • Ich unterstütze die Verwendung von select. Sie erhalten eine weitaus bessere Kontrolle und es ist einfacher, auf die Handhabung mehrerer Steckdosen hochzuskalieren.

    – Chris Becke

    1. März 2017 um 5:55 Uhr

1202340cookie-checkRecvfrom()-Funktion nicht blockierend machen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy