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.


Log in to reply