TCP/IP Kommunikation



  • 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.



  • Beschränk dich erst mal auf das Versenden der Anzahl, den Rest kannst du ja später ergänzen. Und gewöhn´ dir bitte an, ausreichende Informationen zu geben. So Sachen wie "ich verschicke was, aber es kommen komische Daten an" helfen keinem weiter. Also bitte "ich verschicken x als 4 Byte integer mit dem Wert 4711, beim Client bekomme ich beim Zurücklesen aber 1147 raus."



  • @Dome204 du zeigst das Ergebnis nicht. Muss man dir alles einzeln aus der Nase ziehen?

    Wenn du vorher nicht haarklein die Bytes so gelesen hast, wie sie geschrieben wurden, fällst du hier natürlich immer noch auf die Schnauze. Hier sei

    @DocShoe sagte in TCP/IP Kommunikation:

    • 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!

    noch einmal genannt.



  • @Dome204 sagte in TCP/IP Kommunikation:

    strcpy(nachricht, (char*) &pE->Listenperson.Alter);

    Was hat "Alter" für einen Typ? int? Was macht das strcpy dann da?



  • @SeppJ Ich habe die nachfolgenden Programmzeilen, nicht korrigiert, weil ich mich vorerst auf das Übertragen von "a" beschränkt habe.
    Ich bin leider noch sehr ungeübt und Anfänger im Programmieren, das ist mir klar. Vermutlich ist der Fehler trivial, leider ist er für mich nicht so einfach nachvollziehbar.
    Der Rückgabewert von send ist 0
    Beim Server ist a = 1
    Der Rückgabewert von recv ist 4
    Beim Client ist a = 943128576

    Ich bin euch sehr dankbar für eure Hilfen!



  • @Dome204 sagte in TCP/IP Kommunikation:

    Beim Client ist a = 943128576

    Hm. Ich finde es schwierig, hier ins Blaue zu raten.

    Diese Zahl entspricht '8', '7', \0, \0, wenn man das in 4 Bytes aufteilt. Hast du zufällig irgendwie die '8' und '7' im Programm stehen? Ansonsten: was es für alle schwierig macht: du hast zu große Funktionen und zu viele Abhängigkeiten.

    Warum muss dein send z.B. auf copieSockets.fd_array[i] senden? (was ist überhaupt copie? Ein Mix aus copy und kopie?) Deine Senden-Funktion sollte einen Socket als parameter haben, die braucht nicht von irgendeinem i zu wissen.


  • Mod

    Also: Die Kombination send(socket, (char *) &a, sizeof(a), 0); und recv(socket, (char *) &a, sizeof(a),0); mit a als int ist prinzipiell korrekt. In Isolation kann da auch nicht all zu viel bei schief gehen. Jetzt hast du hier halt ein Riesenprogramm, wo keine einzige Funktion irgendwie abgekapselt ist. Wir kennen sogar viele wichtige Teile gar nicht, denn wir wissen nicht wo die Sockets bei dir herkommen und wie die Verbindung hergestellt wurde. Dafür kennen wir ~100 Zeilen Code, der nichts mit dem Problem zu tun hat.

    Aufgaben an dich:

    • Programmgrundgerüst für einen Server schreiben, wo es irgendeine Funktion gibt, die am Ende einen zum Senden bereiten Socket bereit stellt.
    • Programmgrundgerüst für einen Client schreiben, wo es irgendeine Funktion gibt, die am Ende einen zum Empfang bereiten Socket bereit stellt.
    • Auf dem Server sendest du dann genau einen int, mit dem Aufruf in der Art von send(socket, (char *) &a, sizeof(a), 0);
    • Auf dem Client empfängst du dann genau einen int, mit dem Aufruf in der Art von recv(socket, (char *) &a, sizeof(a),0);
    • Sonst machen diese Programm nichts, außer ggf. Ausgaben zum Prüfen der Zwischenwerte.
    • Das guckst du dann nach, ob das passt. Wenn nicht, dann fragst du hier noch mal. Wenn es doch funktioniert, dann baust du das aus zu dem Programm, das du eigentlich haben möchtest.


  • @Dome204 sagte in TCP/IP Kommunikation:

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

    Lies dir genau die Doku zu recv durch. Zeile für Zeile. Wort für Wort.

    recv garantiert nicht so viel Bytes zu lesen wie du angefordert hast. Wenn du z.B. 4 Bytes anforderst aber erst 2 angekommen sind, dann werden halt nur 2 gelesen. Du musst recv dann (mindestens) ein weiteres Mal aufrufen. Natürlich mit entsprechend angepassten Parameters (Ziel-Adresse und Länge).

    ps: Das ist vermutlich nicht der Grund warum dein Programm nicht funktioniert. Aber es ist ein Fehler der sich früher oder später bemerkbar machen wird.


Log in to reply