epoll und Netzwerkprogrammierung



  • Hi Leute,

    nachdem ich in diesem Thread auf epoll für Serverarchitektur aufmerksam gemacht worden bin, hätte ich einige Fragen dazu. Leider finde ich nämlich kaum Dokumentation, Howtos oder Beispiele zu epoll.

    Bei epoll_ctl() kann man über das event Bitfield unter anderem auch folgende Optionen übergeben: EPOLLPRI, EPOLLERR, EPOLLHUP
    In den man Pages steht zwar ein kurzer Satz drin, aber verstanden hab ich es immernoch nicht was diese Optionen wirklich machen.

    Des Weiteren frage ich mich was passiert, wenn ich epoll_wait() aufrufe und ein Netzwerksocket von der anderen Stelle geschlossen wird. Erkennt das epoll_wait(), oder wie kann ich verhindern, dass "tote" Sockets im Set bleiben?

    Ich wäre auch über jeden Link froh, da ich außer den man Pages und diesem Blog keine vernünftigen Informationen finde.

    Danke schonmal!



  • Tobias W schrieb:

    Des Weiteren frage ich mich was passiert, wenn ich epoll_wait() aufrufe und ein Netzwerksocket von der anderen Stelle geschlossen wird. Erkennt das epoll_wait(), oder wie kann ich verhindern, dass "tote" Sockets im Set bleiben?

    Hier habe ich schlicht etwas in den man Pages übersehen:

    Q6: "Will the close of an fd cause it to be removed from all epoll sets automatically?"
    A6: "Yes."

    Falls ich meine restlichen Fragen auch beantworten kann, poste ich das. Wäre aber trotzdem froh über ein paar hilfreiche Links oder Empfehlungen.



  • Bei EPOLLERR sagst du, dass du auch über Fehler auf dem Handle informiert werden willst. Bei EPOLLHUP, dass du über ein Hangup (also Verbindungsende) informiert werden willst und EPOLLPRI ist für Outofband-Daten.



  • Alles klar, das hilft mir sehr weiter. Vielen dank für die Infos!



  • So, nach einer Woche Urlaub hab ich mich wieder an mein epoll Problem gesetzt, aber bekomme es nicht gelöst.

    Folgendes Problem:
    Ich warte mit epoll_wait() auf mehrere Sockets. Einer dieser Sockets wird mittels close() von der anderen Seite geschlossen. Ich hab mir erhofft, dass mittels EPOLLHUP oder EPOLLERR zu erkennen. Doch leider funktioniert das nicht.

    In den events steht auch in diesem Fall nur EPOLLIN. Hier mal ein Codeschnippsel:

    int epfd = epoll_create(10);
    if(epfd < 0)
    {
       // fehlerbehandlung
    }
    ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;
    
    // sockets werden hinzugefügt
    epoll_ctl( /* ... */ );
    
    while(true)
    {
       int fdsAnz = epoll_wait(epfd, events, 10, 2000);
    
       if(fdsAnz < 0)
       {
          // fehlerbehandlung
       }
       if(fdsAnz == 0)
       {
          continue;
       }
    
       for(int i=0; i<fdsAnz; ++i)
       {
          int fd = events[i].data.fd;
          if(events[i].events  & (EPOLLHUP | EPOLLERR))
          {
             // hier erwarte ich bei einem geschlossenen socket zu landen!
             close(events[i].data.fd);
             continue;
          }
    
          // jetzt sollte alles ok sein
          // bearbeiten der sockets...
       }
    }
    

    Und leider springt er nie bei der if Abfrage in Zeile 27 rein. Aber das erwarte ich wenn der Socket geschlossen wird.

    Anstatt dessen returned epoll_wait() sofort und dauernd mit EPOLLIN für den geschlossenen Socket. Aber warum?

    Ich bin für jede Hilfe dankbar!



  • Das ist eigentlich das normale Verhalten. Wenn du nun read aufrufst, dann solltest du die letzten Daten und ein EOF bekommen.



  • Seh ich auch so, aber wofür ist dann überhaupt EPOLLHUP da?



  • Danke erstmal für die Antworten.

    Ich frage mich genau das selbe wie ".....". Hab eigentlich vermutet das man EPOLLHUP zurück bekommt wenn die Verbindung unterbrochen wird. Aber ok, wenn das normal ist geht das auch so.


Anmelden zum Antworten