Winsock TCP optimierung bzw machung^^



  • ACHTUNG das ist meine meinung, das ist kein erfahrungswert oder getestet geschweige denn irgendwie von mir schrifftlich belegbar

    also das send WENIGER zurückgibt als du angegeben hast wird ausschliesslich dann eintreten, wenn du den hardwareseitigen puffer der netzwerkkarte überlastest.
    ich glaube kaum das beim senden von 4 byte wirklich nur 1 byte übertragen wird, aber wenn du jetzt [utopie] 1GB [/utopie] in form eines array in das send pushst dann wird er nur so viel senden können wie gepuffert werden kann, den rest wird er einfach ignorieren.

    die zitate sind zwar schön und gut, aber kann jemand auch mal zeigen wo steht WANN GENAU der wert kleiner wird als das was eingegeben wurde. Weil sonst wird das hier noch n echt buntes verschwörungstheorieraten ...

    falls keiner was passendes findet ...
    ich tipp mal, da sitzt ein kleines männchen mit axt und immer wenn ein datenstrom durchflutscht versucht er ihn zu treffen _



  • Mit setsockopt() kann man zumindest den "per-socket" Receive und Send Buffer verändern. Allerdings steht bei beiden sowas:

    This is unrelated to SO_MAX_MSG_SIZE and does not necessarily correspond to the size of a TCP send/receive window..

    http://msdn2.microsoft.com/en-us/library/ms740476.aspx

    Welchen Wert der TCP (also nicht Winsock) send/receive Buffer hat: k.A. Für Windows XP war mal auf irgendner Seite irgendwas um die 16K erwähnt und das man dessen Wert wohl auch irgendwo verändern kann.

    Aber egal, diese kleine Einschränkung das nicht unbedingt der gesamte Buffer mit einem Schlag weg ist bzw. empfangen ist lässt sich ja nun eigentlich mit geringstem Aufwand beseitigen...



  • @Ceos:
    Ja, blubb. Blubberliblubbdidubb.
    Wir richten uns nach der Doku und sind deswegen doof, und du bist schlauer oder wie?



  • @hustbaer
    klar bin ich das 🙄 (das war ironisch gemeint)

    nur hab ich mich nicht mit der halbherzigen doku zufrieden gegeben und mal nachgedacht und selber probiert ...
    und heraus kam egal wie schnell ich versucht habe zu senden, nur wenn das array hinreichend groß ist habe ich bei send weniger im return als ich reingeschickt habe ... ausserdem war mein kommentar weniger ein angriff sondern eher ne bitte nicht immerwieder dasselbe zu wiederholen und dann es nach eurem willen auszulegen

    PS google iss ja manchmal echt wertlos

    EDIT hab vergessen zu erwähnen das ich NICHT mit setsockopt rumgespielt hab, womöglich hat die option SO_NODELAY einfluss auf das sendeverhalten



  • Ich glaube das "which can be less than the number requested to be sent in the len parameter" bei send steht da wegen non-blocking sockets.

    Im Blocking-Mode würde das doch auch absolut keinen Sinn machen das die Funktion früher abbricht.



  • In der Doku zu WSASend stehts nämlich so: "Given the same buffer situation and a blocking socket, WSASend will block until all of the application buffer contents have been consumed."



  • send sendet ALLES, sofern es sich um einen Socket im blocking-mode handelt. Bei einem Socket im non-blocking - mode muß geprüft werden, wieviel gesendet worden ist und ggf. weiter gesendet werden.

    Allerdings ist das beim recv nicht so. D.h. wenn ich 1000Byte via send verschicke, ist NICHT gewährleistet, daß ich die mit EINEM recv auch alle bekomme. Beim recv ist IMMER zu prüfen, ob die erwartete Datenmenge gelesen werden konnte, und ggf. weiter zu empfangen.



  • mf schrieb:

    In der Doku zu WSASend stehts nämlich so: "Given the same buffer situation and a blocking socket, WSASend will block until all of the application buffer contents have been consumed."

    Was für WSASend() gilt, gilt aber nicht zwangsweise für send() - Was dein Zitat natürlich nicht falsch macht 😉



  • LinkeT schrieb:

    zum thema warum kommen einige bytes (schätze mal gar pakete) nicht an ... TCP garantiert eine "fehlerfreie verbindung" (ist eigentlich quatsch) sie garantiert nur das kein fehler unbemerkt passiert, sowie das ein paket übermittelt wird(falls doch nicht ist da ein fehler) ... die reinfolge sollte eigentlich stimmen je grösser die strecke ist desto höher ist die wahrscheinlichkeit das pakete NICHT in der richtigen reihnfolge ankommen, was u.a. probleme mit VoIP verursacht ... es ist aber für datei transfer kein Problem.

    Verdammt noch mal, WAS denn nun???
    Bitte bitte bitte eine Komplett- Zusammenfassung von jemandem der WIRKLICH Ahnung hat...

    🙄 🙄 🙄



  • BlicksNichtMehr schrieb:

    LinkeT schrieb:

    zum thema warum kommen einige bytes (schätze mal gar pakete) nicht an ... TCP garantiert eine "fehlerfreie verbindung" (ist eigentlich quatsch) sie garantiert nur das kein fehler unbemerkt passiert, sowie das ein paket übermittelt wird(falls doch nicht ist da ein fehler) ... die reinfolge sollte eigentlich stimmen je grösser die strecke ist desto höher ist die wahrscheinlichkeit das pakete NICHT in der richtigen reihnfolge ankommen, was u.a. probleme mit VoIP verursacht ... es ist aber für datei transfer kein Problem.

    Verdammt noch mal, WAS denn nun???
    Bitte bitte bitte eine Komplett- Zusammenfassung von jemandem der WIRKLICH Ahnung hat...

    🙄 🙄 🙄

    das is natürlich bs. tcp garantiert das alles.



  • TCP-Pakete haben im Header eine Sequenznummer, einzelne TCP-Pakete können tatsächlich völlig unsortiert über die Leitungen rennen - ist aber völlig egal da der Zielrechner den Datenstrom dank der Sequenznummer wieder korrekt zusammenbaut.

    Generell kannst du dir bei TCP/IP sicher sein das deine Daten bei recv() in derselben Reihenfolge ankommen wie sie verschickt wurden - Tun sie das nicht hast du garantiert einen Programmierfehler in deiner Anwendung.
    Außerdem kommen die Daten garantiert fehlerfrei oder gar nicht an (was du aber an nem SOCKET_ERROR bemerken wirst)

    Bei VoIP wird eigentlich eher auf UDP gesetzt (sogar für SIP).
    Bei UDP verschickt man einzelne Pakete:
    - Die entweder ankommen oder nicht
    - Die möglicherweise defekt sind (Bei UDP ist die Prüfsumme optional)
    - Die in x-beliebiger Reihenfolge ankommen können

    TCP(=SOCK_STREAM) kann man sich wie nen Telefonat vorstellen: Der Herr "Client" ruft Herrn "Server" an und dann schwafeln die beiden munter los - Hat einer von beiden was nicht verstanden fragt der einfach nochmal nach*

    UDP(=SOCK_DGRAM) ist eher wie Briefversand: Der Herr "Client" schmeißt ne Handvoll Briefe (=Pakete) in den Postkasten und der Postbote bringt die in den Briefkasten von Herrn "Server" 😉
    Zwei Briefe könnten dem Postboten da unbemerkt in den Schnee/Gulli gefallen sein oder ne Briefmarke wurde vergessen oder so - Die kommen dann halt nicht an.
    Und der Postboste schmeißt die Briefe in irgendeiner Reihenfolge in den Briefkasten.

    * Das passiert für uns als Winsock-Nutzer unbemerkt - Wir sehen die Daten immer in korrekter Reihenfolge und müssen uns um sowas nicht kümmern!



  • Danke sehr für die Beschreibung.
    Gerne würde ich noch wissen, wie das nun beim Senden und Empfangen mit der Aufteilung der Bytes der Pakete aussieht, sowohl im UDP als auch im TCP.



  • Bei UDP wird nichts aufgeteilt, die Größe ist beschränkt:

    msdn2: send schrieb:

    For message-oriented sockets (address family of AF_INET or AF_INET6, type of SOCK_DGRAM, and protocol of IPPROTO_UDP, for example), care must be taken not to exceed the maximum packet size of the underlying provider. The maximum message packet size for a provider can be obtained by calling getsockopt with the optname parameter set to SO_MAX_MSG_SIZE to retrieve the value of socket option. If the data is too long to pass atomically through the underlying protocol, the error WSAEMSGSIZE is returned, and no data is transmitted.

    Bei TCP: keine Ahnung wie Windows die Pakete da bildet 😉



  • BlicksNichtMerh schrieb:

    Danke sehr für die Beschreibung.
    Gerne würde ich noch wissen, wie das nun beim Senden und Empfangen mit der Aufteilung der Bytes der Pakete aussieht, sowohl im UDP als auch im TCP.

    Von UDP hab ich keine Ahnung. Für TCP gilt:

    Wenn man blocking - Sockets benutzt, kehrt send erst zurück, wenn er alles auf den Weg gebracht hat oder ein Fehler aufgetreten ist.
    Bei nonblocking - Sockets muß man prüfen, wieviel gesendet wurde und ggf. send wiederholt aufrufen.

    recv kehrt zurück, sobald Daten empfangen wurden oder ein Fehler aufgetreten ist; wenn man eine bestimmte Menge erwartet, muß man prüfen, ob schon alle empfangen wurden - das gilt auch für blocking - Sockets, für nonblocking natürlich sowieso.

    D.h. insbesondere: Wenn ein blocking Socket 1000Byte sendet, und der empfangende blocking Socket per recv Daten bekommt, dann ist NICHT gewährleistet, daß er die 1000 gesendeten Byte in einem Rutsch bekommt. Deshalb braucht man, wenn man eine bestimmte Anzahl Byte erwartet, IMMER eine Schleife.



  • send sendet auch nicht alles, das stimmt nicht. du musst send und recv solange aufrufen bis das gewünschte ergebnis erreicht ist. lass dich nicht lumpen weil irgendwelche kiddies "die erfahrung" gemacht haben, daß es anders ginge. halte dich an die dokumentation.



  • Auszug aus der Doku:

    "... 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 a nonblocking I/O mode. On nonblocking stream-oriented sockets, the number of bytes written can be between 1 and the requested length, ..."



  • Networkopa schrieb:

    send sendet auch nicht alles, das stimmt nicht. du musst send und recv solange aufrufen bis das gewünschte ergebnis erreicht ist. lass dich nicht lumpen weil irgendwelche kiddies "die erfahrung" gemacht haben, daß es anders ginge. halte dich an die dokumentation.

    haha selfowned!



  • Networkopa schrieb:

    send sendet auch nicht alles, das stimmt nicht. du musst send und recv solange aufrufen bis das gewünschte ergebnis erreicht ist. lass dich nicht lumpen weil irgendwelche kiddies "die erfahrung" gemacht haben, daß es anders ginge. halte dich an die dokumentation.

    Doch, send sendet schon alles (bei blocking sockets). Die Beschreibung in der MSDN ist für meinen Geschmack etwas unklar, aber alle Implementierungen machen es wohl so, dass send einfach blockiert, bis alles gesendet werden konnte.

    Ich hatte es auch immer anders verstanden (so wie du), aber nachdem ich in einigen anderen Socket Dokus nachgelesen habe, und nochmal genau in der MSDN drübergelesen habe, musste ich meine ursprüngliche Auslegung revidieren 🙂



  • hustbaer schrieb:

    Die Beschreibung in der MSDN ist für meinen Geschmack etwas unklar

    Da stimme ich Dir zu.



  • aber wo steht dies hustbaer? ich kann dies nicht herauslesen!


Anmelden zum Antworten