TCP/IP Kommunikation
-
@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 dennnachricht
?
-
@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; } } }
-
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 dasstrcpy
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 = 943128576Ich 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 überhauptcopie
? Ein Mix auscopy
undkopie
?) Deine Senden-Funktion sollte einen Socket als parameter haben, die braucht nicht von irgendeinemi
zu wissen.
-
Also: Die Kombination
send(socket, (char *) &a, sizeof(a), 0);
undrecv(socket, (char *) &a, sizeof(a),0);
mita
alsint
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 musstrecv
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.