UDP-Server



  • Ein letztes Problem gibt es noch :

    Beim Port wird mir nicht der zugewiesene Port (auch wenn ich selber einen festlege), sondern Port 0 zurückgegeben. Hat einer von euch eine Idee wie ich das Programm ändern könnte, dass der richtige Port ausgegeben wird?


  • Mod

    Ist das nicht ziemlich eindeutig? Da steht, ein struct sockaddr* wird erwartet. Du uebergibst ein struct sockaddr_in* . Also ganz was anderes. Ein Cast hilft dir vielleicht, den Compiler ruhig zu stellen, das macht den Code aber nicht richtig.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (alle ISO-Standards) in das Forum Linux/Unix verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Danke, jetzt hab ich endlich verstanden wo da das Problem ist.

    Wenn ich von Anfang an struct sockaddr* nutze ist halt das Problem, dass mir wichtige Komponenten wie z.B. der Port in dem Struct fehlen. Darum würde ich schon gerne struct sockaddr_in* verwenden. Aber das scheint ja mit getsockname und recvfrom nicht direkt kompartibel zu sein.

    Gibt es denn echt keine Möglichkeit den Server über struct sockaddr_in zum Laufen zu bekommen?



  • bind
    listen
    getsockname



  • Das ist überhaupt kein Problem.
    struct sockaddr und struct sockaddr_in können problemlos ineinander ge-casted werden. Hintergrund dazu ist das sockets ja nicht nur mit TCP/IP und UDP funktionieren sondern auch mit allen möglichen anderen Protokollen.
    Wenn du mal in sys/socket.h schaust dann findest du dort

    __SOCKADDR_ONETYPE (sockaddr) \
      __SOCKADDR_ONETYPE (sockaddr_at) \
      __SOCKADDR_ONETYPE (sockaddr_ax25) \
      __SOCKADDR_ONETYPE (sockaddr_dl) \
      __SOCKADDR_ONETYPE (sockaddr_eon) \
      __SOCKADDR_ONETYPE (sockaddr_in) \
      __SOCKADDR_ONETYPE (sockaddr_in6) \
      __SOCKADDR_ONETYPE (sockaddr_inarp) \
      __SOCKADDR_ONETYPE (sockaddr_ipx) \
      __SOCKADDR_ONETYPE (sockaddr_iso) \
      __SOCKADDR_ONETYPE (sockaddr_ns) \
      __SOCKADDR_ONETYPE (sockaddr_un) \
      __SOCKADDR_ONETYPE (sockaddr_x25)
    

    Für all diese Protokolle ist, wie man sieht jeweils eine andere Struktur als sockaddr definiert. getsockname und recvfrom sollen aber für alle Protokolle funktionieren.



  • Vielen Dank. Am Casten hat es wirklich nicht gelegen. Ich habe listen() und memset() verwendet und nun klappt es (es wird ein gültiger Port zugewiesen).

    Liebe Grüße,
    re342



  • Wo der Server jetzt funktioniert, wäre es natürlich schön, wenn er durchgehend Daten empfangen könnte und der Socket beim Drücken einer bestimmten oder einer beliebigen Taste geschlossen werden könnte.

    Eine nicht besonders elegante Möglichkeit gibt es ja dafür, und zwar den Daten-Empfangen-Teil in eine Endlosschleife zu packen und das Programm mit Strg+C zu beenden. Eine andere unschöne Variante wäre noch nach jedem mal Daten empfangen ein scanf einzubauen, und je nach Eingabe die Schleife zu verlassen oder nicht.

    Unter Windows gibt es ja eine elegante Möglichkeit über while (!kbhit()).... Gibt es soetwas unter Linux auch?

    Also ich meine etwas in der Art :

    while(Taste nicht gedrückt){
      // bereit Daten zu empfangen
    }
    // Socket schließen über close()
    

    Hat da jemand eine Idee?
    lg re342



  • select



  • Ok danke.



  • myaddr.sin_port = htons(0);

    .... statt "0" muss du da dein port eintragen 🙂

    Beispiel:

    uint16_t port = 4011;
    
    struct sockaddr_in server, client;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);
    

    Edit: achso ist ja schon gelöst, das problem...


Anmelden zum Antworten