Auf zwei Ports gleichzeitig hören
-
Hallo NG,
ich muß in einer Netzwerkanwendung auf einem Port auf Daten warten und auf einem anderen Port auf Kommandos.
- Dazu brauche ich bestimmt zwei Prozesse.
- Jeder von denen braucht einen bind Aufruf für die entsprechenden Ports.
- Je einen listen Aufruf in jedem Prozess um auf connect's zu warten.
- Je einen accept Aufruf um eingehende Verbindungswünsche zu akzeptieren.
- Je einen recv Aufruf um eingehende Daten zu empfangen.Brauche ich aber auch zwei Sockets? Das hab ich nämlich nicht heraus gefunden. Immerhin ist es ein und die selbe Netzwerkkarte und soweit ich es verstanden habe, repräsentiert der Deskriptor die Netzwerkkarte. Und davon hab ich nur eine. Oder weiß der Kernel dann wegen dem bind, welche Daten an welchen Socket geschrieben werden sollen?
Grüße, M. Incani
-
Du brauchst zwei Sockets. Ein Socket repräsentiert eine Verbindung und _nicht_ die Hardware.
Aber du brauchst keine zwei Prozesse! Du kannst einfach man: select(2) oder man: epoll(2) verwenden.
-
Ok, Danke. das schaue ich mir mal an.
Schönen Tag noch,
M. Incanirüdiger schrieb:
Du brauchst zwei Sockets. Ein Socket repräsentiert eine Verbindung und _nicht_ die Hardware.
Aber du brauchst keine zwei Prozesse! Du kannst einfach man: select(2) oder man: epoll(2) verwenden.
-
doch noch eine Frage,
Ich erzeuge die Sockets, binde sie an die Ports, füge sie in ein fd_set ein und rufe dann select statt listen auf, oder?
Dann muß ich nur kucken welcher Socket Daten bereit hält und agiere entsprechend.Gruß M. Incani
rüdiger schrieb:
Du brauchst zwei Sockets. Ein Socket repräsentiert eine Verbindung und _nicht_ die Hardware.
Aber du brauchst keine zwei Prozesse! Du kannst einfach man: select(2) oder man: epoll(2) verwenden.
-
Listen und accept musst Du trotzdem machen. Zunächst erzeugst und bindest Du beide Sockets, dann machst Du listen auf beiden. Dann stopfst Du beide mit FD_SET() in ein genulltes fd_set und merkst Dir den größten Descriptor. Dann führst Du select aus, übergibst als ersten Parameter den größten Descriptor + 1 und nach der Rückgabe kannst Du mit accept() den Client abholen, wenn der entsprechende Socket FD_ISSET() ist.
-
Was meinst Du mit größten Descriptor? Wertmäßig der größte? Spielt die Reihenfolge in der ich die Descriptoren einfüge keine Rolle? Ich verstehe die Manpage so, daß ich den zuerst/zuletzt genannten genannten Descriptor plus eins angebe. Je nachdem was highest numbered bedeutet.
Gruß M. Incani
LordJaxom schrieb:
Listen und accept musst Du trotzdem machen. Zunächst erzeugst und bindest Du beide Sockets, dann machst Du listen auf beiden. Dann stopfst Du beide mit FD_SET() in ein genulltes fd_set und merkst Dir den größten Descriptor. Dann führst Du select aus, übergibst als ersten Parameter den größten Descriptor + 1 und nach der Rückgabe kannst Du mit accept() den Client abholen, wenn der entsprechende Socket FD_ISSET() ist.
-
Ja, den größten Descriptor im Sinne eines Integer-Vergleichs. 10 ist z.B. größer als 6. Die Reihenfolge ist egal, da fd_set ein Bitfeld ist.
-
Guten morgen NG,
hilft mit select eigentlich, wenn ich zwei Verbindungen gleichzeitig bedienen will? Brauche ich denn nicht doch zwei Prozesse? Wie gesagt, habe ich eine Datenverbindung und eine Kommandoverbindung, die ich gleichzeitig bedienen will. Vielleicht hab ich mich gestern nicht richtig ausgedrückt. Aber auf der Datenverbindung kommen permanent Daten an, die verarbeitet werden müssen und auf der Kommandoverbindung muß ich wärend der Datenverarbeitung zusätzlich eingehen und auf die Kommandos reagieren. Deswegen darf die Datenverarbeitung nicht verzögert werden.
Grüße,
M. Incani
-
Genau dafür ist select doch da. Wenn Du nach einem erfolgreichen select (der keine Zeit braucht wenn bereits irgendwo Daten anliegen) mit einer Schleife alle Sockets durchgehst, und diejenigen behandelst die gesetzt sind, verlierst Du nirgendwo Zeit. Du darfst nur nicht blockieren a la "jetzt les mal bis die Verbindung geschlossen wird".
Also im Wesentlichen:
1. fd_set herrichten mit allen geöffneten und horchenden Sockets
2. select()
3. Ist horchender Socket bereit? -> accept
4. Liegen Daten an Datensocket? -> recv
5. Liegen Kommandos am Kommandosocket? -> recv
6. goto 1Wenn die Fragen 3, 4 und 5 gleichzeitig "nein" ergeben würden, wartet select (sofern Du einen Timeout > 0 angegeben hast), ansonsten kehrt select bereits zurück sobald eine der Bedingungen wahr wird.