Timeout bei recv
-
Hi,
gibt es eine Möglichkeit irgendwann abzubrechen, wenn recv() (im blocking modus) eine gewisse Zeit lang keine Daten erhalten hat?
Ich habe bei google von SO_RCVTIMEO in setsockopt gelesen, das funkioniert allerdings nur unter Windows, ich bräuchte es unter Unix (oder besser noch unter windows und unix)...MfG, Herr-Vorragend
-
Timeouts realisiert man glaube ich mit select oder poll.
Aber warum zum Teufel stellst du Fragen zur Netzwerkprogrammierung ins ANSI C Forum??
-
Öhm, sorry, wo muss es denn hin?
Select fällt flach, weil es sich um ein paar hundert Benutzer handelt.
Wie funktioniert das mit poll?MFG, Herr-Vorragend
-
Würde sagen das gehört nach Rund um die Programmierung...
Du machst ja für jetzt für jeden Client einen Thread? Dann musst du ja auch nur einen Client an select übergeben...
Und man müsste glaub ich den Socket auf Non-Blocking umschalten.
-
Warum sollte select ein Problem sein?
poll ist "genauer", das die Stati der einzelnen Verbindungen angeht. Und etwas angenehmer zu benutzen, da es die reingesteckten angeforderten Events nicht einfach überschrieben werden.
Versuch doch mal "man poll".
Und recv() kann man nicht abbrechen, wenn es blockiert. Entweder benutzt Du nonblocking I/O, oder Du benutzt select/poll.
-
Entweder benutzt Du nonblocking I/O, oder Du benutzt select/poll.
Oder? Am besten beides zusammen.
-
Welchen Sinn macht denn beides zusammen? Abfragen, ob eine nicht blockierende Verbindung blockiert?
Bei non-blocking I/O pollt man die Verbindung (hat nichts mit der Funktion 'poll' zu tun) und schaut nach, ob recv 0 zurückliefert. Was eine rigerose Verschwendung an CPU-Zeit ist. Wenn man nicht sowieso noch eine Message-Loop am laufen hat, sollte man davon die Finger lassen.
Ansonsten nimmt man select und schaut nach, welche Verbindung lesbar ist, damit ein recv auf die Verbindung nicht blockiert.
-
Ansonsten nimmt man select und schaut nach, welche Verbindung lesbar ist, damit ein recv auf die Verbindung nicht blockiert.
Und genau dafür muss man in den Non-Blocking Modus schalten. recv/send können sonst nämlich blocken...auch nach einem select.
select mit blocking sockets hat eigentlich keinen Sinn.
-
Naja... das ist jetzt aber mal faktisch falsch.
Ich empfehle Dir man select, ein gutes Tutorial zur Linux / Netzwerkprogrammierung oder das Buch "Unix Network Programming" von W. Richard Stevens.
Select() examines the I/O descriptor sets whose addresses are passed in
readfds, writefds, and exceptfds to see if some of their descriptors are
ready for reading, are ready for writing, or have an exceptional condi-
tion pending, respectively.
-
Der Status kann sich aber nach dem Aufruf von select wieder ändern. Und ausserdem sagt select dir nicht wieviel Bytes du lesen oder schreiben kannst.
-
Warum sollte sich der Status ändern? Wenn meine Verbindung lesbar ist (d.h. Daten da sind), bin ich doch (hoffentlich, wenn es änständig programmiert ist) der einzige, der diese Daten abgreift.
recv liest entweder so viel Daten wie man angibt, oder aber wenn nicht soviel da sind, soviele wie im Empfangspuffer stehen. Wieviel recv gelesen hat, gibt es Dir dann per return Wert zurück. Wenn seit dem select irgendwas kritisches mit der Verbindung passiert ist, bekomme ich ne 0 zurück und weiß, dass ich nicht mehr drauf zugreifen darf (bei Blocking I/O).
-
In der Praxis wird sich der Status beim Lesen vielleicht nicht ändern, aber es ist nirgendwo garantiert.
-
Mag ja sein... praktische Relevanz tangiert wohl aber gegen 0. Zumal die Funktionen designt sind, genau so benutzt zu werden.
-
Normalerweise sendet man dem Gegenüber ja auch was und da kann es schon praktisch sehr gut möglich sein das ein send-Call blockt weil nicht Platz für die ganze Nachricht frei ist. Und dann blockt send eben was nicht gut wäre.
-
Hm stimmt, beim send hast Du recht.
-
öhm, ja ^^
ich konnte euch beiden nicht so ganz folgen ^^ ich hab recv in einer schleife und will einfach nur abbrechen, wenn z.B. 5 minuten nix mehr gekommen ist, wie (mit welcher Funktion) mach ich das denn nun am besten?
btw.: Was passiert, wenn man send() auf einen Socket anwendet, dessen gegenseite gar nicht mehr existiert? (wenn z.B. der PC hängen geblieben ist oder sowas)
MfG, Herr-Vorragend
-
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, *struct timeval timeout);
-
k, thx, ich glaub ich lass das dann aber lieber bzw. überleg mir was anderes, weil 10.000 mal select? ich weiß nicht...
Was passiert, wenn man send() auf einen Socket anwendet, dessen gegenseite gar nicht mehr existiert? (wenn z.B. der PC hängen geblieben ist oder sowas)
-
Dieser Thread wurde von Moderator/in AJ aus dem Forum ANSI C in das Forum Rund um die Programmierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
fang erstmal klein an.
so einen server kannste vielleicht nach einem jahr programmieren.