String einlesen und zerschneiden
-
Nabend,
hab hier ein kleines Problem im Bereich Netzwekrprogrammierung.
Mein Client bekommt eine Nachricht und die muss erst einmal in ihre Bestandtele geschnitten werden, hier stoße ich auf ein Problem.
void drosera_parse (int id, char *ip, char *data) { struct pakage pkg; sscanf(data,"%2hu %2hu %2hu %16s %32s %hu %s", &pkg.total, &pkg.current, &pkg.pkgid, pkg.check, pkg.md5, &pkg.function, pkg.buff); }
Hier Steckt nun mein Problem. Die ersten 6 Variablen können Problemlos ausgelesen werden weil die nem bestimmten Muster entsprungen sind und keine Whitespaces und co beinhaltet. Der Buffer Bereich ist mit Sachen gefüllt die mir fremd sind und daher auch gerne mal ein Leerzeichen beinhalten.
Wie ändere ich das nun am besten damit ich den ganzen Buffer auslesen kann?
Wie könnte ich das sscanf ersetzen?mfg
akoww
-
Hast du denn eine Markierung für das Ende der Nachricht? Wenn ja, bietet sich "%[^\n]" als Formatstring an. Andernfalls kannst du den String auch mit strtok() in Stücke schneiden und die einzelnen Bestandteile einzeln auslesen.
-
Du kannst so ein struct auch einfach binär schicken.
-
beides gut, danke jungs
-
Funktioniert alles, aber wenn der verschickte String >30 Zeichen lang ist, schmiert der Socket einfach ab, weiß aber nicht wieso. Hat jemand Erfahrung damit ? Buffer ist auch groß genug.
-
Solange du nicht die Struktur bekanntgibst, kann man nur Vermutungen anstellen.
-
Zeig mal den Code, mit dem du die Daten empfängst. Und wie sich dieses "schmiert ab" genau äußert, kannst du sicher auch genauer erklären.
(PS: Ich hoffe, du denkst an die Null-Terminierung, bevor du String-Funktionen auf deine Daten loslässt)
-
Wie groß ist der Platz für data und für pkg.buff?
Es geht auch "%29[^\n]"Und sockets müssen nicht auf einmal übertragen werden.
Es kann sein, das nur ein Teil des Strings verschickt wird und dann gibt es für scanf kein '\n'.
-
also hier sind mal die Ausschnitte der send und recv funktionen
nach ~38 schmiert es ab
achso, ich habe die struc in einen string gesteckt und dann verschickt, wo die ausgepackt wird.
#define BUF 2048 ######## char *data =(char*) malloc(BUF); ######## int TCP_send (socket_t *sock, char *data, size_t size) { // size = sizeof(data) if(send(*sock,data,strlen(data),0) == -1) return -1; return 0; } ######## int TCP_recv (socket_t *sock, char *data, size_t size) { // size = BUF -1 unsigned int len; len = recv(*sock,data,size,0); if (len> 0) { data[len]= '\0'; } else if ( len == 0 || len != -1) { return -1; } return len; }
//edit
GOT IT! Es gab nen Overflow an einer anderen Funktion.
-
Zeile 3, 7 und 18 sind sehr unschön. Was soll das?
Warum übergibst du einen Pointer auf den Socket? Das ist nur ne Zahl, kein Objekt!
Zudem scheint mir die Kapselung der Funktionen auch irgendwie sinnlos, aber na gut
-
Bei dem Punkt mit dem Pointer hast du wohl recht.
Naja was die Kapselung anbelangt, mir verschaft es mehr übersicht.
Mein server hat jetzt schon mehr als 1000 Zeilen und das hilft mir ein wenig den überblick zu behalten.Zwischen 3,7 und 18 war blos sehr viel code der unnötig war.
-
Die Kapselung macht Sinn, sobald du in den Funktionen selbst irgendwelche Fehlerbehandlungen hast. Oder sonstige Konstruktionen, die sonst zu aufwändig wären. (z.B. select() um zu verhindern, dass recv() dauerhaft blockiert.) Aber so hast du davon irgendwie nicht viel
-
Du kannst so ein struct auch einfach binär schicken.
Schlechte Idee, grade bei Netzwerkprogrammierung.
Was machst du wenn der Kommunikationspartner ne andere Endianess hat? (Nur mal als Beispiel)?