Winsock: Was passiert, wenn man zu viel sendet?
-
cooky451 schrieb:
Ich glaube nicht dass das so einfach ist. Im WWW wird die Bandbreite ja vom Provider geregelt.
Jo, aber von jedem Provider anders, und uU auch noch bei jedem Kunden anders (je nach Tarif).
Wie theliquidwave schon schrieb, der Sender sendet und ist fertig damit, dem ist es sogar egal, ob die Daten überhaupt gelesen werden, gewchweige denn, wie schnell.
Wenn irgendwo irgendein Puffer überläuft, so daß send die geforderte Menge nicht 'loswird', dann blockiert es, bis es senden konnte.
-
Belli schrieb:
Wenn irgendwo irgendein Puffer überläuft, so daß send die geforderte Menge nicht 'loswird', dann blockiert es, bis es senden konnte.
Und bei WSASend + overlapped (IOCP)? Ist "bytesTransferred" dann 0?
-
send() liefert als Rückgabe wieviele Bytes tatsächlich gesendet wurde. Das kann durchaus mal weniger sein als man angegeben hat. Daher immer in einer Schleife abfragen wieviel tatsächlich gesendet wurde und gegebenenfalls erneur senden.
-
[quote="Belli"]
cooky451 schrieb:
überhaupt gelesen werden, gewchweige denn, wie schnell.
Wenn irgendwo irgendein Puffer überläuft, so daß send die geforderte Menge nicht 'loswird', dann blockiert es, bis es senden konnte.Es blockiert aber nur wenn es nichts senden konnte !
Wenn es nicht alles senden konnte blockiert es nicht und liefert als Rückgabewert wieviel es wirklich gesendet hat.
-
MisterX schrieb:
send() liefert als Rückgabe wieviele Bytes tatsächlich gesendet wurde. Das kann durchaus mal weniger sein als man angegeben hat. Daher immer in einer Schleife abfragen wieviel tatsächlich gesendet wurde und gegebenenfalls erneur senden.
Da seh ich bei overlapped (IOCP) ein Problem. zB:
WSASend() mit 1000 Bytes.
Ist dann irgendwann fertig (completion packet kommt), bytesTransf. ist aber 0. Wäre es 1000, dann wäre es einfach fertig. Wäre es zB. 950, würde einfach innerhalb der completion nochmal WSAsend() mit 50 aufgerufen werden (Und halt so oft, bis es fertig ist).
Aber was macht man dann, wenn es 0 ist? Wenn man gleich wieder sendet, verbraucht man doch extrem viel Leistung, weil extrem oft aufgerufen wird (Bis halt wieder Platz zum senden ist).
-
Meister Lampe schrieb:
Es blockiert aber nur wenn es nichts senden konnte !
Wenn es nicht alles senden konnte blockiert es nicht und liefert als Rückgabewert wieviel es wirklich gesendet hat.Was ich geschrieben habe, gilt für blockierende Sockets, das ist der Zustand, in dem ein Socket nach der Erstellung erst mal ist, bis man ihn uU zu einem nicht blockierenden Socket macht.
Ein send auf einem blockierenden Socket sendet alles oder nichts.
Im Gegensatz dazu empfängt der recv auf einem blockierenden Socket auch Teilmengen, hier ist also eine Schleife vonnöten, sowie die Information, wieviel gelesen werden muß/soll/kann.
-
Hi schrieb:
Da seh ich bei overlapped (IOCP) ein Problem. zB:
WSASend() mit 1000 Bytes.
Ist dann irgendwann fertig (completion packet kommt), bytesTransf. ist aber 0. Wäre es 1000, dann wäre es einfach fertig. Wäre es zB. 950, würde einfach innerhalb der completion nochmal WSAsend() mit 50 aufgerufen werden (Und halt so oft, bis es fertig ist).
Aber was macht man dann, wenn es 0 ist? Wenn man gleich wieder sendet, verbraucht man doch extrem viel Leistung, weil extrem oft aufgerufen wird (Bis halt wieder Platz zum senden ist).Ne, so isses nicht. Wenn du asynchron sendest bei einem sehr langsamen Receiver, dauert das Senden halt länger. Heißt, dein IOCP triggered später als bei einem schnellen Receiver, aber gesendet wird trotzdem (solange der Client die Verbindung nicht schließt). Es wird ja vom IOCP-System afaik erst eine Rückmeldung gegeben, wenn was passiert ist. "0 Bytes gesendet" ist aber nicht "was passiert".
-
Und irgendwann ist dann ein Puffer beim Sender voll... und dann? Crash?
-
Ein send auf einem blockierenden Socket sendet alles oder nichts.
Genau das ist falsch!
-
Hi schrieb:
MisterX schrieb:
send() liefert als Rückgabe wieviele Bytes tatsächlich gesendet wurde. Das kann durchaus mal weniger sein als man angegeben hat. Daher immer in einer Schleife abfragen wieviel tatsächlich gesendet wurde und gegebenenfalls erneur senden.
Da seh ich bei overlapped (IOCP) ein Problem. zB:
WSASend() mit 1000 Bytes.
Ist dann irgendwann fertig (completion packet kommt), bytesTransf. ist aber 0. Wäre es 1000, dann wäre es einfach fertig. Wäre es zB. 950, würde einfach innerhalb der completion nochmal WSAsend() mit 50 aufgerufen werden (Und halt so oft, bis es fertig ist).
Aber was macht man dann, wenn es 0 ist? Wenn man gleich wieder sendet, verbraucht man doch extrem viel Leistung, weil extrem oft aufgerufen wird (Bis halt wieder Platz zum senden ist).Man kann z.B. mit Select abfragen ob ein Socket bereit ist zu senden.
(Wenn ja, kann man sicher sein, das garantiert mindestens ein Byte angenommen wird)
Select selbst blockiert auch.
-
Hier ist die einfache Lösung wie man es macht:
http://www.google.de/url?sa=t&source=web&cd=3&ved=0CDYQFjAC&url=http%3A%2F%2Fbeej.us%2Fguide%2Fbgnet%2Foutput%2Fprint%2Fbgnet_A4.pdf&ei=4aJfTaOTMpGbOsWE1bYN&usg=AFQjCNEEY_R_7HoWJdn32cp6NvDx3MxEqw"Handling Partial send" Seite 38 (bzw. Seite 42 im Adobe Reader weil das Inhaltsverzeichnis nicht mitzählt)
-
Blabla13443 schrieb:
Ein send auf einem blockierenden Socket sendet alles oder nichts.
Genau das ist falsch!
Ich zitier mal aus der MSDN:
If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in nonblocking mode. On nonblocking stream oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both the client and server computers.
-
Belli schrieb:
Blabla13443 schrieb:
Ein send auf einem blockierenden Socket sendet alles oder nichts.
Genau das ist falsch!
Ich zitier mal aus der MSDN:
If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in nonblocking mode. On nonblocking stream oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both the client and server computers.
Du willst was über blockierende Sockets aussagen und bringst ein Zitat auch noch Fett geschrieben über nicht blockierende Sockets.
Wenn da "only on nonblocking stream oriented sockets..." stehen würde, hätte es eine Aussagekraft... aber so sagt es rein nichts über blockierende Sockets aus.
-
Aber baut euch ruhig unsichere Programme. Ist ja nicht mein Problem.
-
Hi schrieb:
Und irgendwann ist dann ein Puffer beim Sender voll... und dann? Crash?
Nein, dann wartet das BS, bis er nicht mehr voll ist. Dann wird weiter gesendet. Ob blockierend oder nicht.
-
Aber wie soll man darauf reagieren...
zB. man will 1 GB versenden; Sendet mit 3 MB/sec. Empfänger hat aber 56k Einwahl. Und man sendet, und sendet, und sendet... und wo stapeln sich die inzwischen zB. fast 500 versendeten MB (Von denen der Empfänger zB. erst 1 MB erhalten hat)? Und wenn es mehr werden? Was passiert und was soll man (die Anwendung) dann tun?
-
Solange Du TCP und blockierende Sockets nutzt solltest Du dich nicht darum kümmern müssen.
Teste es doch einfach mal - sende (übers Netz(!)) schneller als jemand empfangen kann, und guck was passiert
-
Ich möchte aber IOCP verwenden.
-
Hi schrieb:
Aber wie soll man darauf reagieren...
zB. man will 1 GB versenden; Sendet mit 3 MB/sec. Empfänger hat aber 56k Einwahl. Und man sendet, und sendet, und sendet... und wo stapeln sich die inzwischen zB. fast 500 versendeten MB (Von denen der Empfänger zB. erst 1 MB erhalten hat)? Und wenn es mehr werden? Was passiert und was soll man (die Anwendung) dann tun?Versuchen wir es mal darzustellen:
Sender hat 3 mpbs, Empfänger hat 56 kbps. Sowohl Sender- als auch Empfängerpuffer seien 1 MB groß.
Ausgansgsituation: Beide Puffer leer, du willst 1 GB senden
Beim Senden haut das BS von dem GB das erste MB in den Sendepuffer und stößt bei der unterliegenden Schicht das Senden an. Die Pakete werden zum Empfänger geschickt, dank TCP läuft der Empfangspuffer auch nicht über. Dein Programm läuft ja wegen asynch weiter und sobald das eine MB verschickt ist, triggered dein IOCP und du kannst wieder was in den Sendepuffer schieben. Also das nächste Stück von dem GB.Das heißt, du musst die Daten vorhalten. In deinem Beispiel mit den versendeten 500 MB von denen der Empfänger erst ein MB erhalten hat, gäbe es gar keine versendeten 500 MB. Einfach, weil das BS nur immer ein bisschen von dem GB in den Sendepuffer übernimmt, nicht gleich 500 MB. Es gäbe also nur 1 versendetes MB, welches im Sendepuffer darauf wartet, verschickt zu werden. Die restlichen 1023 MB hältst du in deinen Datenstrukturen vor.
-
Hmm, ich hatte mir das anders vorgestellt:
Ich dachte, man würde gleich alles senden, weil es ja nicht blockiert. Also einfach so oft WSASend() aufrufen, bis alle Daten weg sind, sei es 1 GB.Da kommt eine weitere Frage auf: Wie viel darf ich einem WSASend()-Aufruf maximal auf einmal übergeben? Könnte ich auch 1 GB mit einem einzigen Aufruf senden? Soll man das machen? Wie geht man bei WSASend()+overlapped überhaupt vor?