TCP/IP Kommunikation



  • Sehr geehrte Community,
    ich habe in meinem TCP/IP einen Fehler, kann ihn leider nicht finden. Ich hoffe ihr könnt mir weiterhelfen.
    Wenn ich es laufen lasse und die die 4 wähle, wodurch ich bei beiden in die "else if (nummer ==4)"- Schleife komme.
    Das Problem ist folgendes: Der Server soll einen Integer-Wert übertragen. Diesen bekommt er aus einer doppelt verketteten Liste (Wert stimmt, wurde mit "printf" überprüft). Der Client empfängt diesen Wert aber nicht korrekt, weshalb der folgende Programmabschnitt ebenfalls nichts oder etwas Fehlerhaftes empfängt.
    NACHRICHTENLAENGE und nachricht sind in beiden Programmen identisch deklariert worden.
    Ich hoffe ihr könnt mir mit den folgenden Programmabschnitten weiterhelfen:

    Client (Soll empfangen):

            else if (nummer == 4)
            {
                printf("\nSie haben Darstellen gewaehlt.");
                memset(nachricht, 0, sizeof(nachricht));
                iRC = recv(clientSocket, nachricht, sizeof(int),0); //a, also die Anzahl der in der Liste Personen befindlichen Daten wird übergeben
    
                if (iRC == -1)
                {
                    printf("Verbindung geschlossen\n");
                    return 1;
                }
                else
                {
                    int a = atoi(nachricht);
                    if (a > 0)
                    {
                        printf("\nAnzahl an Personen: %i\n", a);//Die Anzahl der Personen ist wichtig um zu wissen wie oft empfangen werden muss
                        for(int i = 0; i<a; i++)
                        {
                            printf("Person %i:", i+1);
    
                            memset(nachricht, 0, NACHRICHTENLAENGE);
                            recv(clientSocket, nachricht, sizeof(nachricht), 0);
                            printf(" Name: %s",nachricht);
    
                            memset(nachricht, 0, sizeof(nachricht));
                            recv(clientSocket, nachricht, sizeof(nachricht), 0);
                            printf(" Alter: %s",nachricht);
    
                            memset(nachricht, 0, sizeof(nachricht));
                            recv(clientSocket, nachricht, sizeof(nachricht), 0);
                            printf(" Gewicht: %s",nachricht);
    
                            memset(nachricht, 0, sizeof(nachricht));
                            recv(clientSocket, nachricht, sizeof(nachricht), 0);
                            printf(" Groesse: %s\n",nachricht);
                        }
                    }
                    else
                    {
                        printf("Liste ist leer\n");
                    }
                }
            }
    

    Server (soll senden)

                        else if (nummer == 4)
                        {
                            fnListeDrucken(&Personen);
                            int a = Personen.anz;
                            send(copieSockets.fd_array[i], (char *)&a, sizeof(int), 0);//Die Anzahl benötigt der Client um zu wissen wie viele Personen ankommen
    
                            if (!a)
                            {
                                printf("Liste ist leer");
                            }
                            else if (a>0)
                            {
                                ListenElem *pE; //pE wird die Adresse von der ersten Person und läuft durch bis die nächste Person ein NULL ist
                                pE = Personen.root;
                                if (!pE)
                                {
                                   printf("\nListe ist leer");
                                }
    
                                while (pE)
                                {
                                    memset(nachricht, 0, sizeof(nachricht));
                                    strcpy(nachricht, pE->Listenperson.Name);
                                    send(copieSockets.fd_array[i], nachricht, sizeof(nachricht), 0);
    
                                    memset(nachricht, 0, sizeof(nachricht));
                                    strcpy(nachricht, (char*) &pE->Listenperson.Alter);
                                    send(copieSockets.fd_array[i], nachricht, sizeof(nachricht), 0);
    
                                    memset(nachricht, 0, sizeof(nachricht));
                                    strcpy(nachricht, (char *) &pE->Listenperson.Gewicht);
                                    send(copieSockets.fd_array[i], nachricht, sizeof(nachricht), 0);
    
                                    memset(nachricht, 0, sizeof(nachricht));
                                    strcpy(nachricht, (char *) &pE->Listenperson.Groesse);
                                    send(copieSockets.fd_array[i], nachricht, sizeof(nachricht), 0);
    
                                    pE = pE->next;
                                }
                            }
                        }
    


    • ist die Verbindung korrekt aufgebaut worden? Wenn du mit einem Tool deiner Wahl die Liste der aktiven Verbindungen von deinem OS anforderst, taucht da deine Verbindung auf?
    • TCP/IP kann Pakete fragmentieren, d.h. deine Nachricht kommt möglicherweise nicht in einem Block an, sondern muss aus mehreren Telegrammen zusammengebaut werden
    • guck dir die Rückgabewerte von send und recv an!

    Ansonsten habe ich keine Ahnung, was du mit "Der Client empfängt diesen Wert aber nicht korrekt" meinst. Was ist denn da nicht korrekt?



  • @DocShoe, danke für den Tipp, ich probiere das direkt aus.
    Ja, die Verbindung sollte richtig aufgebaut sein. Bei anderen Programmabschnitten funktioniert das übertragen fehlerfrei.

    Wenn Beispielsweise in a der Wert 4 steht, empfängt der Client den Wert 1 und bei erneuten anwählen von 4, womit man erneut in die "if else (nummer == 4)"-Schleife gelangt, wird kein Wert empfangen und

                    else
                    {
                        printf("Liste ist leer\n");
                    }
    

    ausgeführt (Zeile 39 bis 42 im obigen Client Code)



  • @Dome204 sagte in TCP/IP Kommunikation:

    int a = atoi(nachricht);

    Du verschickst ein binäres int. Warum willst du hier einen String umwandeln?



  • @manni66 das a benötige ich um zu wissen wie oft ich empfangen muss, weil die Anzahl an Personen in der Liste unterschiedlich sein kann (für die for-Schleife).



  • @Dome204 sagte in TCP/IP Kommunikation:

    das a benötige ich

    Das war nicht die Frage.



  • @manni66
    Um es in der nachfolgenden for-Schleife verwenden zu können.
    Ich hoffe das beantwortet die Frage 😅



  • @Dome204 sagte in TCP/IP Kommunikation:

    @manni66
    Um es in der nachfolgenden for-Schleife verwenden zu können.
    Ich hoffe das beantwortet die Frage 😅

    Nein. Es kommt kein String.



  • @manni66 sagte in TCP/IP Kommunikation:

    Nein. Es kommt kein String.

    Wenn ich das richtig verstehe, habe ich in der folgenden Programmzeile den int nicht korrekt in ein String umgewandelt, weshalb es zu einem falschen Wert bei der Umwandlung kommt.

    iRC = send(copieSockets.fd_array[i], (char *)&a, sizeof(int), 0);
    


  • @Dome204 aus einem int wird kein String, blos weil man (char*) davor schreibt. Du überträgst das int als int und musst es auch wieder als int lesen.

    int a;
    recv(clientSocket, (char*)&a, sizeof(a), 0);
    


  • @manni66 sagte in TCP/IP Kommunikation:

    @Dome204 aus einem int wird kein String, blos weil man (char*) davor schreibt. Du überträgst das int als int und musst es auch wieder als int lesen.

    int a;
    recv(clientSocket, (char*)&a, sizeof(a), 0);
    

    Okay, danke ich verstehe nun den Fehler. Weiß aber leider nicht wie es richtig geht. Könntest du mir einen Tipp geben, wie ich es richtig übertrage?



  • @Dome204 sagte in TCP/IP Kommunikation:

    Weiß aber leider nicht wie es richtig geht

    Du hast die Lösung gerade zitiert.



  • @manni66 oh okay, danke 😅
    Habe es ausprobiert, aber es wird noch immer nicht der richtige Wert übermittelt



  • @Dome204
    Welchen Typ hat denn nachricht?



  • @DocShoe
    nachricht ist ein char Array:

    char                nachricht[NACHRICHTENLAENGE];
    


  • @Dome204
    Ächz....
    Und wie groß ist Nachrichtenlänge?



  • @DocShoe 4096

    #define NACHRICHTENLAENGE 4096
    


  • @Dome204 sagte in TCP/IP Kommunikation:

    Habe es ausprobiert, aber es wird noch immer nicht der richtige Wert übermittelt

    Soso



  • Guck dir den Empfangspuffer in deinem Client mal an, was steht denn da drin? Hast du mannis Tipp schon umgesetzt und wie sieht deiner Empfangsfunktion jetzt aus?



  • Ja, ich habe die Tipps schon umgesetzt.
    So sehen die Abschnitte aktuell aus:

    Client:

    else if (nummer == 4)
            {
                printf("\nSie haben Darstellen gewaehlt.");
                int a;
                iRC = recv(clientSocket, (char *) &a, sizeof(a),0); //a, also die Anzahl der in der Liste Personen befindlichen Daten wird übergeben
                printf("-%i-", a);
                if (iRC == -1)
                {
                    printf("Verbindung geschlossen\n");
                    return 1;
                }
                else
                {
                    if (a > 0)
                    {
                        printf("\nAnzahl an Personen: %i\n", a);//Die Anzahl der Personen ist wichtig um zu wissen wie oft empfangen werden muss
                        for(int i = 0; i<a; i++)
                        {
                            printf("Person %i:", i+1);
    
                            memset(nachricht, 0, NACHRICHTENLAENGE);
                            recv(clientSocket, nachricht, sizeof(nachricht), 0);
                            printf(" Name: %s",nachricht);
    
                            memset(nachricht, 0, sizeof(nachricht));
                            recv(clientSocket, nachricht, sizeof(nachricht), 0);
                            printf(" Alter: %s",nachricht);
    
                            memset(nachricht, 0, sizeof(nachricht));
                            recv(clientSocket, nachricht, sizeof(nachricht), 0);
                            printf(" Gewicht: %s",nachricht);
    
                            memset(nachricht, 0, sizeof(nachricht));
                            recv(clientSocket, nachricht, sizeof(nachricht), 0);
                            printf(" Groesse: %s\n",nachricht);
                        }
                    }
                    else
                    {
                        printf("Liste ist leer\n");
                    }
                }
            }
    

    Server:

    else if (nummer == 4)
                        {
                            fnListeDrucken(&Personen);
                            int a = Personen.anz;
                            printf("-%i-",a);
                            send(copieSockets.fd_array[i], (char *) &a, sizeof(int), 0);//Die Anzahl benötigt der Client um zu wissen wie viele Personen ankommen
    
                            if (!a)
                            {
                                printf("Liste ist leer");
                            }
                            else if (a>0)
                            {
                                ListenElem *pE; //pE wird die Adresse von der ersten Person und läuft durch bis die nächste Person ein NULL ist
                                pE = Personen.root;
                                if (!pE)
                                {
                                   printf("\nListe ist leer");
                                }
    
                                while (pE)
                                {
                                    memset(nachricht, 0, sizeof(nachricht));
                                    strcpy(nachricht, pE->Listenperson.Name);
                                    send(copieSockets.fd_array[i], nachricht, sizeof(nachricht), 0);
    
                                    memset(nachricht, 0, sizeof(nachricht));
                                    strcpy(nachricht, (char*) &pE->Listenperson.Alter);
                                    send(copieSockets.fd_array[i], nachricht, sizeof(nachricht), 0);
    
                                    memset(nachricht, 0, sizeof(nachricht));
                                    strcpy(nachricht, (char *) &pE->Listenperson.Gewicht);
                                    send(copieSockets.fd_array[i], nachricht, sizeof(nachricht), 0);
    
                                    memset(nachricht, 0, sizeof(nachricht));
                                    strcpy(nachricht, (char *) &pE->Listenperson.Groesse);
                                    send(copieSockets.fd_array[i], nachricht, sizeof(nachricht), 0);
    
                                    pE = pE->next;
                                }
                            }
                        }
    

  • Mod

    Du hast also exakt gar nichts von den gegebenen Antworten umgesetzt. PS: Vielleicht war ich zu harsch. Du hast es an einer Stelle umgesetzt. Aber es ist enttäuschend, dass du die anderen Stellen nicht mit korrigiert hast. Hier rächt sich erneut, dass du Abstraktion meidest, und in deinem Programm 10x den fast gleichen Code für den gleichen Zweck wiederholst, mit jeweils allen Fehlern. Anstatt nur einmal, so dass man den Fehler an allen Stellen gleichzeitig korrigieren könnte.

    Du musst erst einmal grundlegend mit C-Datenstrukturen umgehen können, bevor du anfangen kannst, Daten zu versenden. Sowohl beim Einpacken der Nachrichten, als auch das Auspacken ist ungefähr jede Zeile falsch. Da du bisher aber noch nie auf eine der dir gegebenen Erklärungen genauer eingegangen bist, mag ich keine Komplettliste aller Fehler und ihrer Korrekturen geben, und verweise erst einmal auf ein Grundlagenbuch.


Anmelden zum Antworten