Problem mit Sockets



  • Hallo

    ich habe ein kleine Problem und hoffe das mir hier jemand den richtigen Weg zeigen kann.

    Ich möchte ein Programm schreiben das
    1. UDP Nachrichten empfangen kann und
    2. Gleichzeitig auch Nachrichten verschicken kann.

    Ich habe einen Thread erstellt in dem permanent der Befehl rcvfrom ausgeführt wird. Zustätzlich habe ich im Hauptprogramm eine ewige while Schleife welche alle 5 Sekunden eine Nachricht ins Netzwerk schicken soll.

    Mein Problem sind die Sockets.

    Ich habe leider kein Tutorial/keine Beschreibung gefunden das dieses Thema so behandelt.

    Ich habe bisher versucht mit einem oder zwei Sockets zu arbeiten. Bei zwei Sockets stellt sich die Schwierigkeit das ich nicht auf den selben Port binden kann.
    Bei einem Socket muss ich irgendwie zwischendurch die Adressierung anpassen.
    Also von

    addr.sin_addr.s_addr=ADDR_ANY;
    

    auf z.B.

    addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    

    ändern.

    Dies würde jedoch Probleme mit meinem Thread erzeugen.

    Wie löst man dieses Problem normalerweise?

    Danke

    Sledge77



  • addr.sin_addr.s_addr=ADDR_ANY;
    

    auf z.B.

    addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    

    Dies würde jedoch Probleme mit meinem Thread erzeugen.

    Was für ein Problem??
    Ein socket kann empfangen und senden. Du benötigst nicht zwei Sockets.



  • Bitte Entschuldige. Ich bin neu in der Materie.

    Ich habe also einen Socket. In meinem Thread sage ich ihm mit o.g. Code das er auf Nachrichten von jeder IP Addresse lauschen soll. Beim senden gebe ich ihm eine IP Addresse. Ich habe hier die Angst das es Überschneidungen gibt. Also parallel im Thread und im Hauptprogramm versucht wird zu empfangen und zu senden. Deswegen suche ich nach Beispielen o.ä.

    Ich habe gerade im Internet noch geforscht. Dort spricht man auch von Non-Blocking Sockets. Möglicherweise muss ich hier einfach darauf umsteigen. Dann könnte ich mir den extra Thread zum empfangen sparen.



  • Sledge77 schrieb:

    Ich habe also einen Socket. In meinem Thread sage ich ihm mit o.g. Code das er auf Nachrichten von jeder IP Addresse lauschen soll. Beim senden gebe ich ihm eine IP Addresse. Ich habe hier die Angst das es Überschneidungen gibt. Also parallel im Thread und im Hauptprogramm versucht wird zu empfangen und zu senden. Deswegen suche ich nach Beispielen o.ä.

    Das sollte eigentlich kein Problem sein. Das Betriebssystem kümmert sich darum. Außerdem ist IP ja gerade ein Multiplex-Protokoll also genau darauf ausgelegt gleichzeitig mit vielen zu kommunizieren.

    Sledge77 schrieb:

    Ich habe gerade im Internet noch geforscht. Dort spricht man auch von Non-Blocking Sockets. Möglicherweise muss ich hier einfach darauf umsteigen. Dann könnte ich mir den extra Thread zum empfangen sparen.

    Du könntest mit der Funktion select schauen, ob du was empfängtst und darauf reagieren. select bietet dir auch ein Timeout an. Da brauchst du nicht die Sockets auf Non-Blocking setzen. Das ist meistens nicht das, was man will. Blockierende Aufrufe sind immer nett.



  • Reden wir dann von einem Thread der gleichzeitig sendet und empfängt?

    Mein Plan würde dann folgendermaßen aussehen.
    Ich lege zwei queues an. Eine mit Nachrichten die ich empfangen habe und eine die zu sendende Nachrichte enthält. Der Thread schaut dann permanent in die Sende queue und sendet bei bedarf die Nachrichten und danach wird über diesen select Befehl geprüft ob Nachrichten angekommen sind.

    Ist das so umsetzbar?



  • Sledge77 schrieb:

    Reden wir dann von einem Thread der gleichzeitig sendet und empfängt?

    Ja

    Sledge77 schrieb:

    Mein Plan würde dann folgendermaßen aussehen.
    Ich lege zwei queues an. Eine mit Nachrichten die ich empfangen habe und eine die zu sendende Nachrichte enthält. Der Thread schaut dann permanent in die Sende queue und sendet bei bedarf die Nachrichten und danach wird über diesen select Befehl geprüft ob Nachrichten angekommen sind.

    Ist das so umsetzbar?

    Nein. Bei UDP kann der Sender nicht direkt festellen, ob ein UDP-Paket angekommen ist. Schau dir mal den select-Befehlt an, vielleicht weist du dann, was ich meine.



  • Hi

    Ich habe mir mal ein Tutorial zu select() durchgelesen. Wenn ich es richtig verstehe geht es bei dem select() Befehl um das empfangen von Nachrichten von mehreren Clients und dann reagieren in dem ich Nachrichten an diese zurückschicke.

    Der select() Befehl würde meine Anwendung auch blockieren bis das FD_SET sich ändert. Oder? Dann könnte ich prüfen wer noch im Set steht und dann diese Clients behandeln.

    Wenn ich aber dann parallel eine Nachricht schon verschicken will. Wie würde ich das machen?

    Möglicherweise habe ich hier auch nur ein grundsätzliches Verständniss Problem.

    Um Nachrichten von einem bestimmten Port zu erhalten muss ich einen Socket erstellen und diesen auf den Port und ADDR_ANY binden. Nun kann ich mit rcvfrom() abwarten bis hier eine Nachricht eintrifft.

    Parallel möchte ich auf dem selben Port Nachrichten mit sendto() verschicken.

    Hier kommt nun mein Problem. rcvfrom() blockt meine Anwendung. select() würde meine Anwendung auch blocken (soweit ich verstanden habe).

    Also dachte ich mir ich lege das rcvfrom() in einen extra Thread. Dort kann er blocken so lange er will. Ich kann dann in main() Nachrichten schicken. Aber hier hatte ich das Problem mit dem socket (parallele Verwendung zum senden und empfangen).



  • Sledge77 schrieb:

    Der select() Befehl würde meine Anwendung auch blockieren bis das FD_SET sich ändert. Oder? Dann könnte ich prüfen wer noch im Set steht und dann diese Clients behandeln.

    Wenn ich aber dann parallel eine Nachricht schon verschicken will. Wie würde ich das machen?

    [...]
    Hier kommt nun mein Problem. rcvfrom() blockt meine Anwendung. select() würde meine Anwendung auch blocken (soweit ich verstanden habe).

    Du willst doch alle paar Sekunden ein Paket versenden. Select bietet dir ein Timeout. d.h. es kehrt nach einer bestimmten Zeit auf Jeden fall zurück, wenn du das willst.



  • Ich habe meinen denk Fehler gefunden.
    🙄
    Mein erster Ansatz war schon Ok. Aber ich habe bei den Parametern zu sendto to recvfrom etwas übersehen. Ich nutze nun einen Socket in einem Thread und in meinem Hauptprogramm. Der Socket ist für eingehenede Nachrichten an meeinen Port und an Addr_Any gebunden.

    Mein Fehler war das ich dachte das auch für ausgehende Nachrichten jedesmal ein bind duchgeführt werden muss. Stattdessen übergibt man in einem Parameter die Zieladresse und den Port.

    Sorry.
    Aber trotzdem danke für eure hilfe.

    Sledge77


Anmelden zum Antworten