recv socket Problem
-
Hallo zusammen,
ich habe folgende Methode für den Datenempfang;
int rc = 0; std::size_t size = 2000; std::vector<char> buffer(size, 0); rc = recv(s, &buffer.front(), buffer.size(), 0); return std::string(buffer.begin(), buffer.end());Nun ist das so, dass ab einer bestimmten Größe die Daten nicht mehr vollständig ausgelesen werden. Sie werden nur noch doppelt ausgelesen?!? kann mir aber das nicht erklären.
Hat jemand eine Idee?
PS: Die größe des Puffers ist ausreichend
-
Zerstückel die Datei in die Größe deines Puffers und dann send diese.
Wenn sie angekommen sind setz die Stücken in einer Datein wieder zusammen.
-
CCodex schrieb:
Zerstückel die Datei in die Größe deines Puffers und dann send diese.
Wenn sie angekommen sind setz die Stücken in einer Datein wieder zusammen.Nein.
Eine ausführliche Antwort findest du sicherlich in der WinAPI-FAQ. Kurz: recv in einer Schleife aufrufen, bis alle Daten da sind. Oder Statemachine o.Ä. falls die Länge nicht im Voraus feststeht.
-
Hi nochmals,
bei mir werden aber die socketverbindung nicht geschlossen, so schließt es sich aus nach -1 oder 0 zu prüfen. Gibt es eine andere alternative?
-
Du könntest damit anfangen, den Rückgabewert von
recvzu beachten.Das ist Unsinn, weil immer der ganze Puffer zurückgegeben wird:
return std::string(buffer.begin(), buffer.end());Korrekt wäre:
if (rc <= 0) { ... Verbindung verloren } else { return std::string(buffer.begin(), buffer.begin() + rc); }
-
ich könnte doch auch
int rc = 0; std::size_t size = 2000; std::vector<char> buffer(size, 0); rc = recv(s, &buffer.front(), buffer.size(), 0); if(rc<=0) return ""; return std::string(buffer.begin(), buffer.end());Aber die Frage ist immernoch nicht geklärt, warum nach einer bestimmten Anzahl keine Daten mehr ausglesen werden? stattdesen wird nach einer weile die werte immer doppelt ausglesen:
bsp: send: 123456789
recv() -> 123456666
warum keine Ahnung
-
dein letzter code ist falsch weil recv nicht zwingend den ganzen puffer abfüllt -.-
-
Dein recv weiß überhaupt nicht, wieviel auf der anderen Seite gesendet worden ist. Es ist durchaus möglich, dass der Sender in Rutsch 100000 Byte sendet, die in mehreren kleinen Teilen via recv beim Empfänger gelesen werden müssen.
Entweder 'weiß' das Programm, das recv ausführt, wieviel Daten kommen müssen, und muss dann solange recv ausführen, bis alle empfangen wurden, oder aber man braucht ein kleines Protokoll, so dass das recv-Programm erkennen kann, wann es mit lesen fertig ist.
Du solltest wirklich, wie hier schon mal jemand erwähnt hat, im WINAPI - Forum suchen, da ist das nochmal beschrieben und dort gibt es auch Codebeispiele usw.
-
ich weiss ganz genau, dass die größe der Daten 2000Byte überschreitet. Also im worst case wären es tatächlich 2000byte
-
EDIT:wollte natürlich nicht überschreitet schreiben
-
Das ändert nichts an der Tatsache, dass Deine 2000 Byte unterwegs möglicherweise aufgeteilt werden.
-
Beobachter01 schrieb:
ich weiss ganz genau, dass die größe der Daten 2000Byte überschreitet. Also im worst case wären es tatächlich 2000byte
Beobachter01 schrieb:
EDIT:wollte natürlich nicht überschreitet schreiben
Mag sein, dass DU das weißt. Nochmal:
Es ist durchaus möglich, dass Dein recv 100Byte liest, und zwar egal, ob die Gegenstelle 100, 1000, oder 2000 Byte gesendet hat!
Wenn Du also weißt, dass die Gegenstelle irgendwas zwischen 100 und 2000 Byte gesendet hat, und Dein recv liest zB 200Byte, dann weißt Du an der Stelle doch nicht, ob noch was gelesen werden muss, oder ob evtl. nur 200 Byte gesendet wurden, und Du demnach fertig bist mit Lesen.
Und deshalb muss recv in einer Schleife solange aufgerufen werden, bis es alles was gesendet wurde, auch gelesen hat. Dazu aber ist es erforderlich, dass bekannt ist, wieviel gesendet wurde. Dazu mal zwei Möglichkeiten:
Die einfache:
Es werden immer genau 2000Byte gesendet. Dann macht man sooft recv, bis 2000Byte gelesen wurden. Dazu addiert man einfach die Rückgabewerte von recv.
Die kompliziertere:
Es wird irgendwas zwischen 1 und 2000 Byte gesendet. Nun weiß man beim recv natürlich nicht, wann man alles gelesen hat. Es ist ein Protokoll notwendig, um diese Situation sinnvoll behandeln zu können.
-
Hi nochmals,
du hast Recht, das Protokoll zu verändern wird nicht möglich. Ich sende ein codiertes const char* aus diesem Anlass kann durchaus vorkommen das dieses Zeichen auch im eigentlichen Protokoll als Nutzdaten enthalten ist!
Danke euch, wohl oder übel muss ich etwas machen. Es ist sehr wichtig, dass alles empfangen werden
