Async verbinden und trennen mit epoll (Linux)
Ich brauche async verbinden und trennen für die tcp-client mit epoll unter Linux. Es gibt ext. Funktionen in Windows, wie ConnectEx, DisconnectEx, AcceptEx, etc...
Im tcp-server-standard accept-Funktion funktioniert, aber im tcp-client nicht arbeiten verbinden und trennen... Alle Steckdosen sind ungeblockt.
Wie kann ich dies tun?
Dank!
- Das könnte dir helfen : stackoverflow.com/questions/2875002/...
- Als eine mögliche alternative zu den Kommentaren auf der verlinkten HÜLSE Seite, möchte ich vorschlagen, versucht zu
dup
undclose
den Deskriptor (und verwenden Sie das doppelte). Nicht getestet, aber es sollte funktionieren, in meinem Verständnis. Die docs sagen, es ist ein schwerer Fehler bei der Programmierung nicht auf überprüfen Sie den Rückgabewert vonclose
, weil es zurückgeben kann einem vorherigen Fehler. Das ist genau das, was Sie wollen (wennclose
einen Fehler, dannconnect
fehlgeschlagen). Obwohl natürlich, wenn Sieepoll
dann bist du garantiert noch ein OS wogetsockopt(SO_ERROR)
wird nur Arbeit... - Wenn lebensfähig, die einfachste Möglichkeit ist zu warten, bis nach dem connect() zurück, bevor Sie NON_BLOCK.
- Nicht asynchron, es sei denn, Sie verwenden einen worker-thread, aber ich Stimme die Einfachheit ist verführerisch. Plus, DNS-resolve--, die Sie wahrscheinlich brauchen-benötigen einen worker-thread sowieso, es sei denn, Sie blockieren möchten auf diesem (
getattrinfo_a
nicht nur, dass intern auch). So, während Sie block in der Arbeiter-wie auch immer, Sie können auch blockieren, verbinden, zu... - Ich habe 1 Arbeit-thread für alle meine Bedürfnisse (tcp server/client, udp-socket, timerfd). In diesem thread bin ich mit epoll für asynchrone Arbeit. Also ich warte auf epoll_wait(...) und dann tun, was ich brauche. Zumbeispiel: wenn socket listening socket - ich call-accept-Funktion, erstellen Sie neue client mit diesem sockel, und fügen Sie es epoll Warteschlange. Aber in der tcpclient - kann ich nicht hinzufügen, es zu epoll, bevor die Verbindung geschehen ist... Und wenn ich das mache - client eine Verbindung mehrmals (3-4)...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zu tun, ein nicht-blockierendes connect(), vorausgesetzt, die Steckdose wurde bereits non-blocking:
Für den zweiten Fall, wo der connect () - failed with EINPROGRESS (und nur in diesem Fall), müssen Sie warten, bis der socket beschreibbar sein, z.B. für epoll angeben, dass Sie gewartet haben EPOLLOUT auf diesem sockel. Sobald Sie benachrichtigt werden, dass es beschreibbar (mit epoll auch erwarten, um eine EPOLLERR oder EPOLLHUP Ereignis), überprüfen Sie das Ergebnis des Verbindungsversuchs:
In meiner Erfahrung, die auf Linux, connect() nie sofort gelingt, und man muss immer warten, bis writability. Aber, zum Beispiel, auf FreeBSD, gesehen hab ich nicht-blockierendes connect() zu localhost erfolgreich sofort.
Aus Erfahrung, wenn Sie erkennen, nicht-blockierende Verbindung , epoll ist ein wenig anders von select und poll.
mit epoll:
Nach connect () - Aufruf gemacht wird, überprüfen Sie die return-code.
Wenn die Verbindung kann nicht sofort abgeschlossen werden, dann registrieren Sie EPOLLOUT Veranstaltung mit epoll.
Call epoll_wait().
wenn die Verbindung fehlgeschlagen ist, Ihre Veranstaltungen zu füllen mit EPOLLERR oder EPOLLHUP, sonst EPOLLOUT ausgelöst werden.
Habe ich eine "komplette" Antwort hier im Fall, jemand ist auf der Suche nach diesem:
Habe ich versucht das Sonny ' s Lösung und die epoll_ctl zurück ungültiges argument. Also ich denke, vielleicht der richtige Weg, dies zu tun ist wie folgt:
1.erstellen socketfd und epollfd
2.verwenden epoll_ctl zuordnen socketfd und epollfd mit epoll Veranstaltung.
3.verbinden(socketfd,...)
4.überprüfen Sie den Rückgabewert oder Fehlercode
5.wenn errno == EINPROGRESS, tun epoll_wait