Problem mit send() und recv()
-
Hi Leute,
ich hab jetzt damit angefangen mich ein bischen in das Thema "C + Netzwerk" einzulesen.
Ich hab dazu die Tutorials auf www.c-worker.ch durchgelesen und probiert, klappt alles einwandfrei.Jetzt bin ich auf die Idee gekommen mir einen kleinen "File Server" zu schreiben in der Konsole.
Soweit so gut. Server ist "fertig"
Hab jetzt auch angefangen mit dem Client.
Da tritt aber ein probelm auf
ist meine hauptteil meiner sende funktion vom server:
send(user, OK, strlen(OK), 0); while(ftell(file_to_send) != file_len) { read_from_file = fread(msg, 1, MAX_MSG_LEN, file_to_send); sended = send(user, msg, read_from_file, 0); while(read_from_file != sended) { sended += tmp; tmp = send(user, &msg[sended], strlen(&msg[sended]), 0); } tmp = 0; } send(user, END_OF_SEND, strlen(END_OF_SEND), 0);ein teil meiner empfangs funktion:
result = recv(down_sock, msg, strlen(order), 0); if(result > 0 && strcmp(msg, OK) == 0) { while(result != 0 && strcmp(msg, END_OF_SEND) != 0 ) { result = recv(down_sock, msg, MAX_MSG_LEN, 0); if(file != NULL) fwrite(msg, 1, result, file); else fwrite(msg, 1, result, stdout); } }Die 2 defines:
#define END_OF_SEND "__END__" #define OK "__OK__"Jetzt zum Problem:
alles klar Server sendet "OK"
Client empfängt "OK"
Server sendet die datei
Client empfängt aber auf einmal (datei + "END_OF_SEND")
und somit ist der vergleich
msg,END_OF_SEND nicht 0
und er wartet nochmal das was gesendet wirdmeine vermutung das ich recv() funktion vom client zu langsam ist!
Aber kann das sein
?Danke schon im VoRrAuS
Schönen abend noch
-
Doch das kann sein...
Eine Idee wäre, das du immer wieder recv() aufrufst und das ganze an einen String anhängst.
Nach jedem aufruf von recv() durchsuchst du den String nach dem "Ende"-Zeichen.
Alles bis zum "Ende"-Zeichen ist eine Nachricht.Wenn der Server z.B. das hier sendet:
Message1
Ende
Message2
Endekann es sein das der Client beim recv z.b. Das bekommt:
Message1EndeMessage2und beim nächsten aufruf dann nur Ende
Oder eben nur eine Teil der Nachricht beim ersten aufruf von recv() beim Client angekommen ist...
-
send() und recv() arbeiten nicht telegrammorientiert. Mit diesen Befehlen schreibst du nur in die betriebssysteminternen Puffer bzw. liest aus diesen Puffern. Das Betriebssystem kümmert sich dann darum, dass alles, was in diesem Puffer landet, beim Empfänger ankommt, und zwar in der richtigen Reihenfolge. Auf Paketgrößen, Geschwindigkeit usw. hast du als Anwender keinen Einfluß.
Für deine Zwecke mußt du jedes empfangene Paket prüfen, ob das Endekennzeichen darin enthalten ist, wobei das Endekennzeichen nicht am Anfang des Paketes stehen muß. Voraussetzung ist, deine Dateien enthalten niemals das Endekennzeichen selbst. Ansonsten mußt du dir ein anderes Protokoll ausdenken, z.B. ganz am Anfang die Dateigröße übertragen und auf der Empfangsseite dann die Anzahl der empfangenen Zeichen mitzählen.
Rob'
-
Ich verstehe nicht wieso das immer zu solcher Verwirrung führt. Bei einer Datei erwartet ja auch keiner dass er bei Read genau eine "Message" zurückbekommt die als ganzes mittels Write geschrieben wurde.
Liegt vielleicht an den etwas unglücklich gewählten Regeln für blocking IO bei Sockets (=dass nicht immer soviel gelesen wird wie man angibt sonder min. 1 Byte bis max. das was man angegeben hat).