Logik hinter Winsockets
-
@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 einemsend
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 ausrecv
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, 4Nachricht 2:
Die Bytes an Positionen 1 bis 2 sind: 5, 1Nachricht 3:
Die Bytes an Positionen 6 bis 9 sind: 2, 6, 3, 1Hast 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).
-
@hustbaer sagte in Logik hinter Winsockets:
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" Bytes bis zum nächsten ist eine Zeile).
Die Zeilen bekommt das Programm ja schon mit (es kann ja das '\n' sehen), aber nichts davon, wie es auf der Platte (oder sonstwo) gespeichert ist.
Bei TCP bekommt man die Daten in der richtigen Reihenfolge - oder gar nicht.
Wie das gemacht wird ist für den Anwender erstmal magisch. Darum braucht er sich auch nicht kümmern.
-
@DirkB sagte in Logik hinter Winsockets:
Die Zeilen bekommt das Programm ja schon mit (es kann ja das '\n' sehen), aber nichts davon, wie es auf der Platte (oder sonstwo) gespeichert ist.
Das Programm bekommt die Bytes die im File stehen. Dass es die
\n
Bytes als Zeilenwechsel interpretiert ist Entscheidung des Programms. Dem OS oder dem File ist das alles egal.
-
@CUser1
Ich denke du versuchst zu viele Dinge auf einmal zu verstehen. Du kennst Spiele aus Sicht des Spielers ("Truhe aufmachen") und schaust dir jetzt mit Wireshark Pakete an die über's Netzwerk wandern. Und versuchst jetzt alles was dazwischen passiert zu verstehen. Das ist denke ich zu viel.Wieso fängst du nicht mal mit einem Sockets Tutorial an? Und nicht bloss lesen. Wenn du sicher sein willst dass du es wirklich verstanden hast musst du selbst mindestens 1-2 kleine Programme schreiben die mit Sockets arbeiten.
-
@hustbaer Das was ich als Packet bezeichne ist was das Spiel macht "Packet 0x5 ID HANDLUNG" oder so => mach Truhe auf.
Mir ist mittlerweile klar, dass seitens des TCP Layers das ganze dann vlt. in 3 Teilen verschickt wird mir ist nur wichtig zu verstehen, dass die Reihenfolge stimmt, vermutlich wird dann nummeriert, damit der Client weiß was der Server zuerst schicken wollte und vice versa. Darum haben die Packets ja vermutlich einen "FF" drinnen oder so, damit man sie später parsen kann, wenn mit recv() zwei aufeinmal einlangen.
-
TCP/IP garantiert das. Entweder es das Zeug kommt in der richtigen Reihenfolge und ohne Lücken an, oder es kommt nicht an.
vermutlich wird dann nummeriert, damit der Client weiß was der Server zuerst schicken wollte und vice versa.
Ja. Das passiert aber für die Programme völlig transparent. Darum kümmert sich ein Teil des Betriebssystems. (Der Teil der als "TCP/IP Stack" bezeichnet wird, was wie gesagt nichts mit der Datenstruktur namens Stack zu tun hat.)
Darum haben die Packets ja vermutlich einen "FF" drinnen oder so, damit man sie später parsen kann, wenn mit recv() zwei aufeinmal einlangen.
Jetzt versuchst du wieder das ganze auf Protokollebene zu verstehen ohne dich mit den Details des Protokolls auseinanderzusetzen. Das wird nicht funktionieren. Das macht keinen Sinn. Zwei sinnvolle Varianten:
- Akzeptiere einfach dass Daten bei TCP/IP irgendwie magisch in der richtigen Reihenfolge und ohne Lücken ankommen und hinterfrage nicht wie.
- Nimm dir die Zeit und befasse dich ausgiebig mit den Details wie TCP/IP auf Protokollebene funktioniert.
Irgendwo dazwischen rumraten was bestimmte Bytes in den Netzwerkpaketen bedeuten können macht wenig Sinn. Das fürht bloss zu Verwirrung und falschen Ideen darüber wie das alles funktioniert.
Wenn du Wireshark verwenden willst: guck dir einfach nur den rekonstruierten Datenstrom an. Nicht die einzelnen Pakete. Vergiss die. Weil dir die Grundlagen fehlen die du bräuchtest um die Bedeutung zu verstehen. Oder wie gesagt lern die Grundlagen.
-
@hustbaer sagte in Logik hinter Winsockets:
Irgendwo dazwischen rumraten was bestimmte Bytes in den Netzwerkpaketen bedeuten können macht wenig Sinn.
Deine Daten werden in mehrere Frames verpackt. Fast jede Ebene vom TCP/IP Stack packt eigene Informationen dazu. Sender-/Empfangsadresse, Checksummen, ...
Das da die IP-Adresse-und Port ist klar, aber im LAN kommt noch die Ethernet-Adresse dazu - im WAN sind das wieder andere Adressen.
Da bleibt dann "verstehen wollen" oder "nur anwenden". Wieviel Zeit hast du, ohne von deinem eigentlichen Problem abzukommen?
-
@hustbaer Irgendwie verstehe ich auch nicht ganz wovon du redest ich arbeite an einem Clientless Bot und was soll ich sonst anschauen als die einzelnen Pakete und den Begriff Packet verwendet quasi jede Hacking community obwohl es den nicht gibt.
Im Prinzip genügt es mir zu wissen, dass die Reihenfolge stimmt das mit Puffern bis alles da ist ergibt eh Sinn.
Und ob wenn recv 200 Bytes aus dem Buffer nimmt und da 5 Packets drinn sind, muss man die parsen, wie soll es sonst sein.
-
@CUser1
Ich hab nie geschrieben dass es den Begriff Paket nicht gibt. Ich hab geschrieben dass du ihn für etwas verwendest was auf der Ebene von TCP/IP nicht exisitert. Was du denke ich immer noch tust.Wenn ich einen Nachricht habe die aus sagen wir 2000 Bytes besteht. Dann kann ich diese mit einem Aufruf an
send
übergeben.
TCP/IP kann diese dann als 1 Stück verschicken oder auch in 2, 3, 4... Stücken. Es kann sogar sein dass das 1. Stück der Nachricht mit anderen Daten zusammengefasst wird und so ein Stück rausgeht das den letzten Teil einer vorherigen Nachricht enthält plus den ersten Teil der neuen Nachricht.Auf der Gegenseite ist es dann so, dass du von
recv
ein Stück Daten bekommst sobald das in der korrekten Reihenfolge nächste Stück Daten da ist. (Es wird nicht gewartet bis alle Stücke einer Nachricht da sind, denn TCP/IP kümmert sich nicht um Nachrichten.)Und diese Stücke bezeichnet man als Pakete.
Auf dem Weg können die dann u.U. nochmal in kleinere Stückchen zerlegt werden - diese kleineren Stücke nennt man dann Fragmente.
Du scheinst aber den Begriff "Paket" für das zu verwenden was ich als Nachricht bezeichne - also in diesem Fall den ganzen Block mit den 2000 Bytes. Und das ist sehr verwirrend.
Im Prinzip genügt es mir zu wissen, dass die Reihenfolge stimmt das mit Puffern bis alles da ist ergibt eh Sinn.
Vielleicht meinst du das richtig, aber falls nicht: Es wird nicht gepuffert bis "alles da" ist. Es wird gepuffert bis zumindest das erste Stück da ist -- egal wie klein dieses Stück ist, egal wie gross die ursprüngliche Nachricht war.
Und ob wenn recv 200 Bytes aus dem Buffer nimmt und da 5 Packets drinn sind, muss man die parsen, wie soll es sonst sein.
Der Begriff Paket macht hier wieder keinen Sinn. Der Satz macht für mich nur Sinn wenn du das meinst was ich als Nachrichten bezeichnet habe. Und in dem Fall: es können auch 0.2 oder 5.5 Nachrichten drinnen sein.
-
@hustbaer Ok ich gehe davon aus, dass ich es verstanden habe seit der 1/2 des Themas obwohl das mit "nicht warten bis eine ganze Nachricht da ist" auch wieder neu ist. Meine ausdrucksweise ist sehr oberflächlich, weil mich das TCP technische - was auch sehr spannend ist - nur "nebenbei" interessiert momentan. Ich bezeichne die Nachrichten als Packets, und das wenn das "Packet" fragmentiert versendet wird auch als Packets. Danke vorerst, der Thread war sehr hilfreich!
-
@CUser1 sagte in Logik hinter Winsockets:
@hustbaer Ok ich gehe davon aus, dass ich es verstanden habe seit der 1/2 des Themas
Es macht nicht den Eindruck als ob du es verstanden hättest.
obwohl das mit "nicht warten bis eine ganze Nachricht da ist" auch wieder neu ist.
Nein, ist es nicht. Du passt bloss nicht auf und verwendest die falschen Begriffe - sowohl beim Schreiben als auch beim Versuch zu verstehen was wir dir schreiben. Das kann natürlich nicht funktionieren. Ich hätte mehrfach versucht dich darauf hinzuweisen, aber das ignorierst du einfach.
Meine ausdrucksweise ist sehr oberflächlich, weil mich das TCP technische - was auch sehr spannend ist - nur "nebenbei" interessiert momentan.
Wieso fragst du dann immer wieder und wieder nach diesen Details, wenn eh kein Wille da ist sich wirklich mit der Antwort zu befassen?
Ich bezeichne die Nachrichten als Packets, und das wenn das "Packet" fragmentiert versendet wird auch als Packets.
Ja. Und du meinst so kann man sinnvoll was lernen?
Danke vorerst, der Thread war sehr hilfreich!
Bitte. Das war übrigens der letzte Beitrag von dir auf den ich antworten werde, denn meine Zeit ist mir zu schade um zu versuchen dir noch weitere Dinge zu erklären. Ich hoffe du verstehst wieso und lernst was daraus.
-
Für mich ist es neu Herr je und ich habe momentan ganz einfach mit dem Reversen zu tun und es ist jetzt nicht wirklich relevant wie TCP funktioniert. Ich frage nach den Details, weil ich das als Chat betrachte und es sonst langweilig ist als Pausenfüller hier kommt ja sowieso nur ein sinnvoller Thread die Woche also sei froh, dass es mich gibt. Ich mache mir keinen Stress, bin froh etwas aufzuschnappen, ich kann das jetzt lesen oder in einem Jahr, weil das ein reines Hobby ist.