−BootLag−-BootLag-−BootLag− schrieb:
Das heißt, wenn ich das richtig verstanden habe, die Angabe 1024 gibt nicht an, dass das die Funktion 1024 Bytes empfangen MUSS?
Genau. Die 1024 sind die Obergrenze (der Puffer ist ja nicht unendlich gross), die Untergrenze ist wie gesagt 1 bzw. 0.
Rufe ich die besagte Funktion mit 1024 genau einmal auf(ist blockierend) und es werden von der Gegenseite nur 512 Bytes gesendet, dann werden auch nur 512 Bytes empfangen und die Funktion ist fertig und das Programm läuft weiter?
Nö. Bzw. ja, kommt drauf an wie du es meinst.
Es werden dann nicht nötigerweise 512 Bytes empfangen, sondern zwischen 1 und 512 Byte - aber natürlich maximal 512 Byte, da ja nicht mehr weggeschickt wurden.
Wie viel es genau sind, ist mehr oder weniger Zufall.
Wenn du eine Ethernet Verbindung hast, wirst du kaum jemals was anderes als 512 Byte sehen, da sich 512 Byte noch in einem Paket ausgehen. Allerdings sollte man sich darauf niemals verlassen, denn es ist nicht garantiert dass die 512 Byte auf einmal empfangen werden. Wenn davor bereits andere Daten übertragen wurden wird es auch real vorkommen dass NICHT alles auf einmal ankommt, bzw. wenn die Verbindung aus irgend einem Grund eine sehr kleine MTU hat.
Wenn du den Effekt beobachten möchtest, dann nimm statt 512 Byte einfach mal 64KB, und schick die Daten über ein echtes Netzwerk. D.h. NICHT nur VON deinem PC ZU deinem PC, sondern vielleicht von deinem PC an die Public-IP deines Routers, so dass der die Daten wieder zu deinem PC zurückschickt --- passendes Port-Mapping vorausgesetzt. Und je langsamer das Netzwerk desto besser, da der Effekt dann umso eher beobachtbar wird.
Was recv macht kann man sich (stark vereinfacht) ca. so vorstellen:
int recv(SOCKET s, void* buffer, int buffer_size)
{
int gepufferte_daten = daten_in_empfangspuffer(s);
if (gepufferte_daten == 0)
{
if (!ist_blocking_socket(s))
return 0; // bei non-blocking sockets wird nicht gewartet
warte_auf_daten(s); // wartet bis min 1 Byte empfangen wurde, ggf. auch mehr
gepufferte_daten = daten_in_empfangspuffer(s);
assert(gepufferte_daten > 0); // jetzt muss was da sein
}
int transfer_size;
if (gepufferte_daten > buffer_size)
transfer_size = buffer_size;
else
transfer_size = gepufferte_daten;
// "transfer_size" Bytes aus dem Empfangs-Puffer in den User-Puffer kopieren
// (und gleichzeitig aus dem Empfangs-Puffer entfernen)
kopiere_daten_aus_empfangspuffer(s, buffer, transfer_size);
return transfer_size; // dem Aufrufer zurückgeben wie viel Bytes wirklich transferiert wurden
}