Logik hinter Winsockets



  • Warum haltet das Programm an, wenn man recv aufruft?

    Blockierende Aufrufe sind quasi ein service, den Dir die Biblio liefert ....
    Normal kannst Du auch pollen (non blocking sockets), aber das ist grad bei wiederholenden asynchronen Dingen nicht unbedingt der einfachste/intuitivste Weg.

    Du hasst also meistens die Wahl:

    -> non assync mit pollen
    -> pseudo assync über features wenn es framework / biblio supported
    -> richtig/eigenes assync (multithreading / multiprozessing) und dann kannst "easy" blocking sockets verwenden.

    Da netztwerk und assync von natur aus irgendwie passen wird der workflow mit letzterem meist auch einfacher ....

    Andere Programmiersprachen tun sich hingegen mit pseudo nebenläufigkeit (Assynchron Input Output) leichter und implementieren da schon support.
    C++ und socket schnittstelle ist ...... besser ne abstraktere Bib verwenden IMHO (fürs Üben und verständniss mal abgesehen)



  • @RHBaum sagte in Logik hinter Winsockets:

    -> richtig/eigenes assync (multithreading / multiprozessing) und dann kannst "easy" blocking sockets verwenden.

    Das ist doch auch synchrones IO, bloss halt mit Threads.
    "Richtiges" async ist mit APIs wie CreateIoCompletionPort oder kqueue. Das ist dann aber eher noch komplizierter als non-blocking.

    ps: Asynchronous hat kein doppel-S.



  • @hustbaer Also beim Debuggen sind alle Threads auf Pause, dann wird mit Singlestep 1 send() gecalled mit 52 Bytes vermutlich "Auth Inhalt". Und wenn es da drüber läuft, wird das gesendet und obwohl der Process eingefroren ist, wird dann vom Server was erwidert und dann sendet es nochmal etwa 50 Bytes aber m. E. auch was programmspezifisches.

    Aber ich verstehe nicht wieso du das als sinnlos bezeichnest.

    Weil ich dann einen neuen Thread brauche, weil ich ja auch andere Sachen bearbeiten will.

    Was genau versteht man unter synchron in dem Kontext? Nehmen da beide Endpunkte die Uhrzeit bevor sie anfangen was zu tun oder um was geht es da?



  • @CUser1 sagte in Logik hinter Winsockets:

    @hustbaer Also beim Debuggen sind alle Threads auf Pause, dann wird mit Singlestep 1 send() gecalled mit 52 Bytes vermutlich "Auth Inhalt". Und wenn es da drüber läuft, wird das gesendet und obwohl der Process eingefroren ist, wird dann vom Server was erwidert und dann sendet es nochmal etwa 50 Bytes aber m. E. auch was programmspezifisches.

    Welches "es" sendet nochmal 50 Byte? Das angehaltene Programm? Das wäre komisch. Ich vermute eher dass 2x send aufgerufen wird.

    [quote]Aber ich verstehe nicht wieso du das als sinnlos bezeichnest.[/quote]

    Weil ich dann einen neuen Thread brauche, weil ich ja auch andere Sachen bearbeiten will.

    Naja wieso verwendest du dann blocking-IO wenn du nebenbei auch noch andere Sachen machen willst?

    Was genau versteht man unter synchron in dem Kontext? Nehmen da beide Endpunkte die Uhrzeit bevor sie anfangen was zu tun oder um was geht es da?

    Synchron heisst dass die Funktion die Arbeit abgeschlossen hat wenn sie zurückkehrt.

    Non-blocking IO ist synchron: kann sein dass was gemacht wurde oder aber auch nicht, aber auf jeden Fall passiert nichts mehr nachdem die Funktion zurückgekommen ist.

    Blocking IO ist auch synchron: wenn kein Fehler passiert wird die Funktion immer was machen, und wartet eben ggf. so lange wie nötig.

    Asynchron nennt man APIs wo man z.B. mit einem Aufruf sagen kann "fang jetzt bitte an Daten zu empfangen, bitte an diese Adresse schreiben, maximale Grösse ist X, gib bescheid wenn du fertig bist". Die Operation läuft dann im Hintergrund. Bis die Operation abgeschlossen ist darfst du dann den an die Funktion übergebenen Puffer auch nicht freigeben - wird ja im Hintergrund noch verwendet. (Beim asynchronen Empfangen kommt man meist eh nicht auf die Idee dass man den Puffer freigeben wollen würde. Die Einschränkung gilt aber genau so für's asynchrone Senden.)
    Und dann gibt es irgend einen Mechanismus mit dem man informiert wird dass die Operation jetzt abgeschlossen ist, inklusive Ergebnis (OK oder Fehlercode).
    Wie das funktioniert hängt von der jeweiligen API ab. Und es gibt leider keine die auf allen Systemen funktioniert. Nichtmal eine die auf allen POSIX Systemen funktioniert.

    Wenn's dir nur um Windows geht: IO Completion Ports.



  • @CUser1 sagte in Logik hinter Winsockets:

    Und wenn es da drüber läuft, wird das gesendet und obwohl der Process eingefroren ist, wird dann vom Server was erwidert und dann sendet es nochmal etwa 50 Bytes

    Die Sockets sind ja ein Bestandteil vom Betriebssystem und nicht vom Programm.
    Die Daten werden ja im Hintergrund gesendet und empfangen.
    Du kannst deinen Prozess im Debugger anhalten, aber nicht das Betriebssystem.



  • Vielleicht hilft ein wenig ASCII Art:

    Synchron:
    ----R##########r---------

    Asynchron:
    ----R#r#############N----

    Legende:
    R : Aufruf der recv Funktion
    r: recv Funktion kehrt zurück
    N: Benachrichtigung dass die Operation abgeschlossen ist.
    #: Time-Slot in dem die Operation noch aktiv ist, d.h. in dieser Zeit können Daten vom OS in deinen Lesepuffer geschrieben werden.
    - Time-Slot "ausserhalb" der Operation



  • @DirkB sagte in Logik hinter Winsockets:

    Die Sockets sind ja ein Bestandteil vom Betriebssystem und nicht vom Programm.
    Die Daten werden ja im Hintergrund gesendet und empfangen.
    Du kannst deinen Prozess im Debugger anhalten, aber nicht das Betriebssystem.

    Das stimmt schon. Trotzdem wird das OS nicht für 52 Byte ein Paket rausknallen wenn es noch weitere 50 Byte zu senden hat und die insgesamt 102 Byte gemeinsam an send übergeben wurden. Als erste Daten einer Verbindung. Das macht Windows einfach nicht, und soweit ich weiss auch kein anderes System.

    Daher meine Vermutung dass der Code 2x schnell hintereinander send aufruft, erst mit 52 Byte und dann nochmal mit 50 Byte.



  • @CUser1 Über welche Funktion genau steppst du drüber? Die send Funktion der Winsock API?



  • @hustbaer Das zweite Packet ist Server -> Client, war wohl gestern schon zu müde. Alles Unfug mit 2 mal send().

    Was ich gerade draufgekommen bin: recv() liefert nicht 0 wenn keine Daten zum Lesen vorhanden sind, sondern wenn es sonst welche Probleme gibt oder? Weil sonst würde bei !recv() ja das Example Programm schließen.

    Noch was:

    Ich habe gelesen bei TCP ist Reihenfolge wie gesendet wird nicht immer korrekt. Hat man darum immer einen switch der die Packet ID vergleicht? Das jeweilige Packet selbst ist aber immer gleich oder? Also wenn ich jetzt mit send() 8192 Bytes rausknalle, dann kommen die zumindest richtig an. Weil sonst würde ja bei einem Billard PC Spiel zuerst der Queue benutzt und dann der Spieler bewegt?

    Und nochwas: Wird über die Packet size geprüft ob alles übertragen wurde? Weil der Server kennt den Inhalt des Packets ja ggf. nicht und wenn nur einmal send() aufgerufen wird muss das ganze ja zuverlässig ankommen. Bleibt es in der send solang bis es einen Callback gibt oder so? Wenn man von Packetverlusten spricht, bedeutet das dass im Hintergrund etwas 10 mal gesendet wird, weil die Data nicht übereinstimmt mit der mitgesendeten Datasize?



  • @CUser1 sagte in Logik hinter Winsockets:

    @hustbaer Das zweite Packet ist Server -> Client, war wohl gestern schon zu müde. Alles Unfug mit 2 mal send().

    OK. Das ist dann normal. Wie schon geschrieben wurde wird das Paket ja wenn es ankommt erstmal vom OS bearbeitet und im Empfangspuffer abgelegt. Das funktioniert auch wenn das Programm gerade im Debugger angehalten ist. Und das reicht damit dir das Paket von Wireshark/... angezeigt wird.

    Was ich gerade draufgekommen bin: recv() liefert nicht 0 wenn keine Daten zum Lesen vorhanden sind, sondern wenn es sonst welche Probleme gibt oder? Weil sonst würde bei !recv() ja das Example Programm schließen.

    Naja, das ist doch alles ganz gut dokumentiert, nicht? recv liefert 0 wenn die Verbindung von der Gegenseite "graceful" geschlossen wurde. Also ein "normaler" Disconnect. Oder -1 bei Fehler. Wobei im non-blocking Modus auch "keine Daten verfügbar" als Fehler gilt.

    Noch was:

    Ich habe gelesen bei TCP ist Reihenfolge wie gesendet wird nicht immer korrekt. Hat man darum immer einen switch der die Packet ID vergleicht? Das jeweilige Packet selbst ist aber immer gleich oder? Also wenn ich jetzt mit send() 8192 Bytes rausknalle, dann kommen die zumindest richtig an. Weil sonst würde ja bei einem Billard PC Spiel zuerst der Queue benutzt und dann der Spieler bewegt?

    Mit Switches hat das nichts zu tun. TCP Daten werden in Paketen verschickt. Rausgeschickt werden die dabei normalerweise schon immer in der richtigen Reihenfolge. Nur können unterschiedliche Pakete u.U. unterschiedliche Wege zum Ziel nehmen, und daher auch in der falschen Reihenfolge ankommen. Dazu ist in jedem Paget eine sog. "Sequence Number" enthalten. Das ist quasi die Position die das 1. Byte des Pakets im gesamten Stream einnimmt. Anhand dieser Sequence Number kann der Empfänger die Pakete dann wieder in der richtigen Reihenfolge zusammensetzen. Darum kümmert sich der TCP/IP Stack - das Programm muss dazu nichts extra machen.

    Und nochwas: Wird über die Packet size geprüft ob alles übertragen wurde? Weil der Server kennt den Inhalt des Packets ja ggf. nicht und wenn nur einmal send() aufgerufen wird muss das ganze ja zuverlässig ankommen. Bleibt es in der send solang bis es einen Callback gibt oder so? Wenn man von Packetverlusten spricht, bedeutet das dass im Hintergrund etwas 10 mal gesendet wird, weil die Data nicht übereinstimmt mit der mitgesendeten Datasize?

    Wenn das Serverprogramm send sagt, dann werden die Daten erstmal in einen Sende-Puffer kopiert der vom TCP/IP Stack verwaltet wird. Dann werden die Pakete verschickt. Die Daten bleiben aber so lange im Puffer bis die Gegenseite sie mit einem ACK Paket "quittiert" hat. (Hierbei kommt wieder die Sequence Number zum Einsatz.) Dauert es zu lange bis die Daten quittiert werden, dann schickt der TCP/IP Stack sie einfach nochmal -- und startet den "warten auf ACK" Timer neu. D.h. die Daten werden evtl. auch drei mal oder öfter verschickt. Wenn das sehr oft passiert, dann macht der Stack erstmal eine kleine Pause (paar Sekunden) wo er keine Pakete mehr schickt. Danach probiert er dann erstmal ein Paket zu schicken. Wird dieses wieder nicht quittiert macht der Stack eine etwas längere Pause. Und irgendwann gibt er auf und erklärt die Verbindung für kaputt. Ab dem Zeitpunkt bekommt das Server Programm von allen Socket Funktionen dann einen Fehler gemeldet. Es wird auch ein Paket zum Client geschickt das diesem mitteilt dass die Verbindung abgebrochen wurde. Wobei dann die Chance gross ist dass der Client das Paket nie bekommt - es hat ja davor schon immer nur Probleme gegeben.

    Kommt allerdings nach so einer Retransmission ein passendes ACK daher, dann wird wieder weiter gesendet.

    Interessant dabei ist auch dass das der einzige zuverlässige Mechanismus ist über den bei TCP/IP die Sendegeschwindigkeit kontrolliert wird. Wenn der Sender zu schnell sendet so dass irgend ein Teil in der ganzen Kette bis zum Empfänger nicht mehr mit kommt, dann werden irgendwo Pakete verworfen. Das merkt der Sender dann weil er ja kein ACK bekommt. Er versendet dann nicht nur die Daten neu, sondern fährt auch die Sendegeschwindigkeit ein wenig zurück. Sobald für einen längeren Zeitraum keine Retransmissions mehr nötig waren fährt der Sender die Sendegeschwindigkeit wieder ein bisschen hoch. Bis wieder Pakete verloren gehen. Usw. So pendelt sich die Sendegeschwindigkeit im Schnitt quasi von selbst auf dem Niveau ein bei dem alle Glieder der Übertragungskette gerade noch mitkommen.



  • @hustbaer Das heißt um es kurz zu wiederholen:
    connect() ist notwendig, damit send() und recv() verwendet werden können.

    Werden die ACK Packets mit Size 54 also immer als Art Callback versendet, wenn einer der beiden Seiten eine Info verschickt hat? Empfangsbestätigung sozusagen.

    Angenommen ich schicke jetzt 400 Byte auf einmal, dann kommen die unterschiedlich schnell an, wie du beschrieben hast, und dann haben die eine Sequencenumber wie Packet 1/3 , 3/3, 2/3 und erst wenn beim Empfänger im TCP Stack (ist der Teil vom virtuellen RAM des Prozesses?) zu 3/3 zusammengebaut und sobald das vorhanden ist, liefert recv() den Inhalt?

    Kann es sein das recv auch 3 unterschiedliche Packete aufeinmal liefert? Wie oben erwähnt mit 3 mal send()? Was ist wenn da dann das 3te vor dem ersten ankommt? Muss da der Server vorher auf das ACK warten, um sowas zu vermeiden? Oder alles auf einmal schicken, und den Client parsen lassen, damit man weniger ACKs braucht? ACK = Acknowledged = Angekommen?

    Und dieses rote Connection interrupt packet ist dann der abrupte Shutdown? Wird dass vom OS gesendet, wenn es merkt dass ein Prozess terminiert, der noch Sockets registriert hat?



  • @CUser1 sagte in Logik hinter Winsockets:

    @hustbaer Das heißt um es kurz zu wiederholen:
    connect() ist notwendig, damit send() und recv() verwendet werden können.

    Sozusagen.

    Werden die ACK Packets mit Size 54 also immer als Art Callback versendet, wenn einer der beiden Seiten eine Info verschickt hat? Empfangsbestätigung sozusagen.

    Keine Ahnung wie gross die Pakete sind. Callback würde ich das auch nicht nennen. Es ist halt einfach eine Empfangsbestätigung.

    Angenommen ich schicke jetzt 400 Byte auf einmal, dann kommen die unterschiedlich schnell an, wie du beschrieben hast

    400 Byte werden normalerweise in einem einzigen Paket versendet. Nehmen wir lieber 4000 an, dann kommt es besser hin.

    und dann haben die eine Sequencenumber wie Packet 1/3 , 3/3, 2/3

    Nein. Die Sequence-Number zählt Bytes. D.h. das erste Paket hat z.B. Sequence-Number 0, das zweite dann vielleicht 1500 und das dritte 3000.

    und erst wenn beim Empfänger im TCP Stack (ist der Teil vom virtuellen RAM des Prozesses?) zu 3/3 zusammengebaut und sobald das vorhanden ist, liefert recv() den Inhalt?

    Nein. recv liefert etwas sobald es etwas liefern kann. Eine TCP/IP Verbindung ist ein Stream. Die Information wie viel der Sender mit einem send Aufruf gleichzeitig weggeschickt hat kann auf der Empfängerseite nicht mehr rekonstruiert werden. Es kann sein dass der Sender 1x 4000 Byte schickt und ankommen tun 4x 1000. Es kann aber genau so sein dass der Sender 4x 1000 Byte schickt und alle 4000 kommen aus recv gleichzeitig raus.

    Wenn du sowas wie Message-Grenzen brauchst musst du dich selbst darum kümmern. Kannst du dir vorstellen wie wenn du aus einem File liest. Da kannst du beim Lesen auch nicht feststellen in welchen Stücken das File geschrieben wurde.

    Und nein, der TCP/IP Stack ist nicht teil des virtuellen Speichers. Der TCP/IP Stack ist überhaupt kein Speicher. Sondern typischerweise ein Teil des Kernels. Und der verwendet typischerweise auch Kernel Mode Virtual Memory.

    Kann es sein das recv auch 3 unterschiedliche Packete aufeinmal liefert?

    Ja.

    Wie oben erwähnt mit 3 mal send()? Was ist wenn da dann das 3te vor dem ersten ankommt?

    Der TCP/IP Stack des Empfänger wartet immer so lange bis er das jeweils nächste Paket bekommen hat. Und in dem Moment wo das eintrifft gibt er dir alle Daten die er aktuell zusammenhängend vorliegen hat. Also angenommen der Empfänger hat Pakete 2, 3, 5 und 10 - und jetzt kommt Paket 1 daher. Dann bekommst du in diesem Moment Pakete 1, 2 und 3 in einem Rutsch von recv zurück.

    Muss da der Server vorher auf das ACK warten, um sowas zu vermeiden?

    Nein.

    Oder alles auf einmal schicken, und den Client parsen lassen, damit man weniger ACKs braucht? ACK = Acknowledged = Angekommen?

    ACK = Acknowledge = Bestätigung

    Und wenn dich das ganze so im Detail interessiert, dann würde ich vorschlagen du googelst dir den Rest. Wird langsam etwas mühsam das alles im Detail zu erklären.

    Und dieses rote Connection interrupt packet ist dann der abrupte Shutdown? Wird dass vom OS gesendet, wenn es merkt dass ein Prozess terminiert, der noch Sockets registriert hat?

    Rot? Interrupt Packet? Bahnhof? Meinst du ein RST? Oder FIN? ...?



  • @hustbaer Kann es sein dass recv die Packets gar nicht vom TCP Stack herunternimmt wie Peekmessage? Oder ist das wieder eine Option?

    Mit dem roten meine ich, dass wenn man das Programm schließt, dann beendet anscheinend das OS die Verbindung, und wird bei Wireshark rot angezeigt.

    Aber wie funktioniert es dann, dass die Reihenfolge gewährleistet ist? Woher kennt der Server die richtige Packetreihenfolge, wenn die Packet irgendwie daherflattern?



  • @CUser1 sagte in Logik hinter Winsockets:

    Aber wie funktioniert es dann, dass die Reihenfolge gewährleistet ist? Woher kennt der Server die richtige Packetreihenfolge, wenn die Packet irgendwie daherflattern?

    Die Daten kommen ja nicht alleine.
    Die werden ja in einem Paket mit Informationen versand.
    Dort stehen Empfänger, Absender, Größe, ... drin
    Diese Pakete werden auch noch in andere Pakete verpackt.
    Und in einem dieser Informationen steht auch die Paketnummer.

    Bisher wurde TCP beschrieben.
    Es gibt aber noch andere Protokolle in der TCP/IP Familie.
    z.B UDP - da muss sich der Anwender um die Reihenfolge und Wiederholungen kümmern.

    Wird z.B beim streamen benutzt, wenn ein Paket verloren ist, dann nützt eine Wiederholung da auch nichts mehr: Bild-/Tonaussetzer.

    Hast du denn schon bei Zotteljedi rein geschaut?

    Oder das Buch von W. Richard Stevens „Programmieren von UNIX-Netzwerken“



  • @DirkB Noch nicht wirklich, weil ich auch andere Tutorials durchgehe die ähnliche Inhalte haben.

    Die Reihenfolge ist aber wichtig, weil sonst kennt sich der Server nicht aus, wenn man in einem Spiel zuerst das Gold nimmt und dann die Truhe öffnet?

    Also wenn ich 3 mal sende: Walk, Open Chest, Take Gold z. B., dann muss es ja auch in dieser Reihenfolge ankommen?

    Wartet der Server auf das ACK oder hat man dann einfach Pech gehabt, wenn das 2te Packet vor dem 1sten einlangt?

    Und werden Packets immer als ganzes verschickt oder?

    Weil wenn ich die Hälft von einem Packet habe und dann kommt das dritte dann ergibt die erste Hälfte mit der dritten keinen Sinn?



  • @CUser1 sagte in Logik hinter Winsockets:

    Also wenn ich 3 mal sende: Walk, Open Chest, Take Gold z. B., dann muss es ja auch in dieser Reihenfolge ankommen?
    Wartet der Server auf das ACK oder hat man dann einfach Pech gehabt, wenn das 2te Packet vor dem 1sten einlangt?
    Und werden Packets immer als ganzes verschickt oder?

    TCP sorgt dafür, dass die Daten in der richtigen Reihenfolge ankommen - da brauchst du nichts mehr machen.
    Wenn Paket 4 nicht ankommt, bekommst du die Daten von 5 nicht, sondern einen Fehler.

    Die Daten werden gesendet, wenn dafür Zeit ist, evtl. werden mehrere Daten gesammelt.

    Diese TCP Pakete werden z.B noch in Ethernet-Pakete verpackt - damit hast du bei Sockets aber nichts mehr zu tun.
    (Es sei denn, du willst einen TCP-Stack neu entwickeln)



  • @CUser1 sagte in Logik hinter Winsockets:

    @hustbaer Kann es sein dass recv die Packets gar nicht vom TCP Stack herunternimmt wie Peekmessage? Oder ist das wieder eine Option?

    Du hast den Begriff TCP/IP Stack falsch verstanden. Damit ist nicht eine Stack-Datenstruktur gemeint sondern einfach die Programmteile im OS die sich darum kümmern dass TCP/IP funktioniert.

    Und wenn dein Programm recv aufruft, dann werden die entsprechenden Daten natürlich aus dem Empfangspuffer entfernt. Sonst würde der RAM Verbrauch ja enorm ansteigen wenn du z.B. grosse Files runterlädst.

    Mit dem roten meine ich, dass wenn man das Programm schließt, dann beendet anscheinend das OS die Verbindung, und wird bei Wireshark rot angezeigt.

    Keine Ahnung was Wireshark rot anzeigt, ich hab das ewig nicht verwendet.

    Aber wie funktioniert es dann, dass die Reihenfolge gewährleistet ist? Woher kennt der Server die richtige Packetreihenfolge, wenn die Packet irgendwie daherflattern?

    Ich hab das jetzt glaub ich schon mehr als 1x erklärt: in jedem Paket steht eine Sequence-Number drinnen, die angibt "wo es hingehört". Schau dir bitte die diversen Seiten zum Thema TCP/IP auf Wikipedia an. Und dann google selbst nochmal zu dem Thema. Da findet man haufenweise gute Beschreibungen wie das alles funktioniert.



  • @CUser1
    Vielleicht hilft ein konkretes Beispiel.
    Wenn ich dir folgende Nachrichten gebe...

    Nachricht 1:
    Die Bytes an Positionen 3 bis 5 sind: 7, 2, 4

    Nachricht 2:
    Die Bytes an Positionen 1 bis 2 sind: 5, 1

    Nachricht 3:
    Die Bytes an Positionen 6 bis 9 sind: 2, 6, 3, 1

    Hast du jetzt genug Informationen alle 9 Bytes in der richtigen Reihenfolge zu nennen? Ja. Und genau so funktioniert das mit TCP/IP.

    In dem Beispiel weiss das OS im Empfänger PC ja dass es dem Programm noch keine Daten gegeben hat. D.h. wenn das Programm recv aufruft, dann weiss das OS dass es erstmal auf das Byte an Position 1 warten muss. Wenn es jetzt die erste Nachricht bekommt (=das erste Paket), dann sieht es dass darin die Bytes an Positionen 3 bis 5 enthalten sind. So steht es ja schliesslich in der Nachricht. D.h. das OS kann dem Programm noch nix geben, weil Position 1 ja immer noch fehlt. Es merkt sich die 3 Bytes also und gibt dem Programm erstmal noch nichts. Dann kommt das 2. Paket mit den Bytes an Position 1 bis 2. Das OS sieht jetzt dass es ohne Lücken Positionen 1 bis 5 beinander hat. Es gibt dem Programm also diese 5 Bytes, und merkt sich dass das nächste Byte auf das gewartet wird das mit Position 6 ist. Und da die ersten 5 Bytes dem Programm ja bereits gegeben wurden, löscht das OS diese natürlich aus seinem Puffer.



  • @hustbaer Ok Danke jetzt verstehe ich es, dass heißt das OS sammelt die Fragmente bis ein ganzes Packet da ist, und dann erst scheint es bei recv() auf.

    Das andere mit Reihenfolge funktioniert wohl über die ACK wie DirkB geschrieben hat? Wenn ich im Spiel eine Truhe öffne, dann sendet es zuerst: Gehe zur Truhe, warte auf ACK, öffne Truhe, warte auf ACK, Nimm Goldschatz, warte auf ACK. Oder es sendet alles auf einen Schlag damit die Reihenfolge gewährleistet ist und ein Packet als ganzes bearbeitet wird? Weil wenn Gold nehmen vor Truhe öffnen ankommt wäre es blöd?



  • @CUser1 sagte in Logik hinter Winsockets:

    @hustbaer Ok Danke jetzt verstehe ich es, dass heißt das OS sammelt die Fragmente bis ein ganzes Packet da ist, und dann erst scheint es bei recv() auf.

    Fast. Das was du als Fragmente bezeichnest nennt man normalerweise Pakete. Und das was du als Paket bezeichnest gibt es nicht.

    Das andere mit Reihenfolge funktioniert wohl über die ACK wie DirkB geschrieben hat?

    Welches andere mit Reihenfolge? ACK spielt dabei auch erstmal überhaupt keine Rolle. ACK wird erst interessant wenn man berücksichtigen muss dass auch mal Pakete verloren gehen.

    Wenn ich im Spiel eine Truhe öffne, dann sendet es zuerst: Gehe zur Truhe, warte auf ACK, öffne Truhe, warte auf ACK, Nimm Goldschatz, warte auf ACK.

    Ich bin mir nicht sicher ob ich verstehe was du meinst. Ein Programm wartet auf jeden Fall nicht auf irgend welche ACK, denn das Programm bekommt davon überhaupt nichts mit.

    Oder es sendet alles auf einen Schlag damit die Reihenfolge gewährleistet ist und ein Packet als ganzes bearbeitet wird?

    Nochmal: Das was du unter Paketen verstehst gibt es in TCP/IP nicht. Genau so wenig wie ein File etwas von Zeilen weiss. Eine Zeile in z.B. einem Textfile ist eine Interpretation des Programms das das File liest (z.B. alles vom letzten "new line" Byte bis zum nächsten ist eine Zeile).


Anmelden zum Antworten