Server/Client Portausgabe



  • Hallo,

    kann mir jemand weiterhelfen wieso der Port nicht richtig ausgegeben wird:
    https://dl.dropboxusercontent.com/u/17888900/TCPServerPort.JPG

    Danke und frohe Weihnachten 😉



  • Bitte den fraglichen Code per Copy&Paste hier ins Forum (mit Code-Tags).

    Was erwartest du was asugegeben werden soll, was wird ausgegeben?

    Gibt der Compiler eine Warnung zu der Zeile aus?



  • Habe zum test einfach einmal diesen Server genommen: http://www.binarytides.com/programming-udp-sockets-c-linux/

    In dieser Zeile soll er mir die IP und den Port ausgeben, wie man unten im Bild bei den watch Variablen sieht, die IP die wird richtig umgewandelt jedoch stimmt der Port nicht und ich kann mir nicht erkläre wieso der falsch ausgegeben wird, die Umwandlung von Big Endian in Little Endian (short 16bit) sollte so funktionieren.

    #include<stdio.h> //printf
    #include<string.h> //memset
    #include<stdlib.h> //exit(0);
    #include<arpa/inet.h>
    #include<sys/socket.h>
    
    #define BUFLEN 512  //Max length of buffer
    #define PORT 8888   //The port on which to listen for incoming data
    
    void die(char *s)
    {
        perror(s);
        exit(1);
    }
    
    int main(void)
    {
        struct sockaddr_in si_me, si_other;
    
        int s, i, slen = sizeof(si_other) , recv_len;
        char buf[BUFLEN];
    
        //create a UDP socket
        if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
        {
            die("socket");
        }
    
        // zero out the structure
        memset((char *) &si_me, 0, sizeof(si_me));
    
        si_me.sin_family = AF_INET;
        si_me.sin_port = htons(PORT);
        si_me.sin_addr.s_addr = htonl(INADDR_ANY);
    
        //bind socket to port
        if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
        {
            die("bind");
        }
    
        //keep listening for data
        while(1)
        {
            printf("Waiting for data...");
            fflush(stdout);
    
            //try to receive some data, this is a blocking call
            if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == -1)
            {
                die("recvfrom()");
            }
    
            //print details of the client/peer and the data received
            printf("Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
            printf("Data: %s\n" , buf);
    
            //now reply the client with the same data
            if (sendto(s, buf, recv_len, 0, (struct sockaddr*) &si_other, slen) == -1)
            {
                die("sendto()");
            }
        }
    
        close(s);
        return 0;
    }
    

    Daten werden übertragen, komischerweise steht im Port immer ein anderer Wert.



  • Das ist der Port vom Client... der wird (wenn er nicht expliziet angegeben wird) vom Betriebssystem dynamisch und "zufällig" vergeben.

    Wie sieht der Client-Code aus?



  • Zum Testen habe ich es oben mit netcat gemacht.

    Bei dem Sample code wird im Client der port so zugewissen siehe link oben, Client:

    si_other.sin_port = htons(PORT);
    


  • Im Client wird nur gesagt, wohin das Paket geschickt werden soll. Der Absender wird nicht näher spezifiert und wird daher vom Betriebssystem vergeben.

    Ich glaube dir fehlt grundlegendes Verständnis zu UDP/IP.



  • Danke für die Antwort

    Ich bin gerade dabei es mir anzulernen.
    Wie kann ich den den Port festlegen?



  • So wie man es auch im Server macht. Mit bind.

    Dies ist aber nicht nötig und allgemein auch nicht zu empfehlen.
    Ein Port kann pro IP nur ein einziges mal verwendet werden. Soll heißen du kannst dann nicht zwei Clients zugleich benutzen; Der zweite würde beim bind einen Fehler zurückgeben...
    (Hinter einem Router kommen dann auch wieder andere Ports raus, da das NAT sie umschreiben muss.)



  • Vielen Danke für die Hilfe.

    Habe es auch nicht vor mir ging es nur ums Verständis.

    Frohe Weihnachten



  • Noch ne Kleinigkeit: ntohs liefert dir, wie der Name schon sagt, ein short (bzw. jetzt ein uint16_t ) zurück. %d ist aber für die Ausgabe von einem int da.


Anmelden zum Antworten