Socket-Programmierung mit C++ unter Unix
-
Hallo!
Der Threadtitel ist ja ziemlich allgemein - das liegt aber daran, dass auch meine Fragen relativ allgemein sind. Ich lese mich jetzt anhand von einigen (meiner Meinung nach ziemlich guten) Internet-Tutorials und Code-Beispielen seit einigen Tagen in die Socket-Programmierung unter Linux und C++ ein. Ich habe inzwischen auch die Grundlagen verstanden, jetzt stellen sich mir jedoch ein paar Fragen, auf die ich auch durch Googlen keine Antwort finden kann. Wenn es schon Antworten gibt, würde ich um Links bitten - weil ich konnte leider nichts finden.
Vorweg, ich habe inzwischen eine Server- und eine Client-Anwendung zum Laufen bekommen und auch eine Interaktion zwischen beiden geschafft. Ich habe lediglich Fragen zum Verständnis:
Mit "bind(...)" verknüpfe ich den Socket mit einer Adresse, zum Beispiel localhost, und einem speziellen Port auf diesem Computer. Mit listen(...) horcht der Socket dann den entsprechenden Port ab. Soweit so gut. Nun soll sich aber auch eine fremde Anwendung mit dem Server verbinden können, also erstelle ich, wie zuvor beim Server, einen zweiten Socket und eine zweite Socket-Adress-Struktur. Mit accept() wird nun dort eine Verbindung von der Client-Anwendung hinein gespeichert. Nun bin ich bei meiner Frage: Wie kann ich es bewerkstelligen, dass sich mit meinem Server-Socket mehrere Client-Anwendungen verbinden können? Gibt es etwas wie ein "onConnect"-Ereignis beim Server-Socket, wodurch ich eine Funktion ausführen kann, jedes Mal wenn eine neue Verbindung aufgebaut wird? Und gibt es eine Möglichkeit, einen Socket wieder von einer Adresse zu lösen (sowas wie "unbind()") ohne ihn zu löschen? Oder zumindest das "listen()" zurückzuziehen? Ich bin zwar nicht gezwungen mit accept() Verbindungen anzunehmen, aber solange der Socket noch den entsprechenden Port abhört bzw. an ihn gebunden ist, ist meine Anwendung ja zum Beispiel über "netstat" auffindbar.
Das waren so die Dinge, die mir im Moment noch überhaupt nicht klar sind. Ich würde mich über Hilfe sehr freuen und vielen Dank im Voraus!
Liebe Grüße!
-
Einen socket schließen tust du mit close().
Für einen Server der mit mehreren Clients funktionieren soll, solltest du mit Threads arbeiten.
-
Es gibt verschiedene Lösungen um mehrere Verbindungen mit einem Server zu behandeln. Prinzipiell kannst du zB Threads oder Prozesse nutzen. Ein Prozess wartet auf accept und startet für neue Verbindungen einen eigenen Prozess/Thread um die Verbindung zu behandeln. Alternativ gibt es die Möglichkeit mit man: select(2) (wobei es dafür mittlerweile bessere APIs gibt, die aber Systemabhängig sind: man: epoll für Linux und man: kqueue für BSD/OSX und noch andere Sachen. libevent ist zB ein Wrapper für die ganzen Geschichten) zu überprüfen auf welchen sockets Ereignisse (Daten zum lesen, Möglichkeit zum schreiben, Fehler) warten. Daneben gibt es noch andere async bzw. Mischmethoden.
Wenn du C++ benutzt, lohnt sich sicher ein Blick in boost::asio. Dabei handelt es sich um eine Bibliothek, die die ganzen Netzwerkgeschichten schön verpackt.
Etwas wie unbind gibt es nicht. Da bleibt dir nur übrig das Socket zu schließen und dann ein neues zu öffnen.