Frage

Ich erstelle meine eigene benutzerdefinierte Serversoftware für ein Spiel in Java (das Spiel und die Original -Server -Software wurden mit Java geschrieben). Es gibt keine Protokolldokumentation, daher muss ich die Pakete mit Wireshark lesen.

Während ein Client verbindet, sendet der Server die Ebene der Ebene im GZIP -Format. Bei etwa 94 Paketen zum Senden des Levels stürzt mein Server den Client mit einem ArrayIndexoutOfBoundSexception ab. Gemäß der Capture -Datei vom ursprünglichen Server wird zu diesem Zeitpunkt ein TCP -Fenster -Update gesendet. Was ist ein TCP -Fenster -Update und wie würde ich eine mit einem Socketchel senden?

War es hilfreich?

Lösung

TCP -Fenster werden für die Durchflussregelung zwischen den Gleichaltrigen auf einer Verbindung verwendet. Mit jedem ACK -Paket sendet ein Host ein Feld "Fenstergröße". In diesem Feld heißt es, wie viele Daten Bytes, die Host erhalten können, bevor es voll ist. Der Absender soll nicht mehr als diese Datenmenge senden.

Das Fenster wird möglicherweise voll, wenn der Client Daten nicht schnell genug empfängt. Mit anderen Worten, die TCP -Puffer können sich füllen, während die Anwendung etwas anderes als aus dem Sockel auslesen. In diesem Fall sendet der Client ein ACK -Paket mit dem "Fenster voll" -bit eingestellt. Zu diesem Zeitpunkt soll der Server das Senden von Daten aufhören. Alle Pakete, die an eine Maschine mit einem vollständigen Fenster gesendet werden nicht anerkannt werden. (Dies führt dazu !)

Dies ist ein TCP -Stand. Es kann aus vielen Gründen passieren, aber letztendlich bedeutet es nur, dass der Absender schneller überträgt, als der Empfänger liest.

Sobald die App am Empfangsende zum Lesen aus der Sockel zurückgekehrt ist, wird einige der gepufferten Daten abgelassen, die etwas Platz freisetzen. Der Empfänger sendet dann ein "Fenster -Update" -Paket, um dem Absender mitzuteilen, wie viel Daten er übertragen kann. Der Absender beginnt mit der Übertragung seiner gepufferten Daten und der Verkehr sollte normal fließen.

Natürlich können Sie wiederholte Stände erhalten, wenn der Empfänger durchweg langsam ist.

Ich habe dies so formuliert, als ob der Absender und der Empfänger unterschiedlich sind, aber in Wirklichkeit tauschen beide Gleichaltrigen mit jedem ACK -Paket Fenster -Updates aus, und beide Seiten können das Fenster füllen lassen.

Die Gesamtnachricht ist, dass Sie keine Fenster -Update -Update -Pakete direkt senden müssen. Es wäre tatsächlich eine schlechte Idee, einen zu fälschen.

In Bezug auf die Ausnahme, die Sie sehen ... wird wahrscheinlich nicht durch das Fenster -Update -Paket verursacht oder verhindert. Wenn der Kunde jedoch nicht schnell genug liest, verlieren Sie möglicherweise Daten. In Ihrem Server sollten Sie den Rückgabewert von Ihrem Socket (Write () -Anrufe überprüfen. Es könnte weniger sein als die Anzahl der Bytes, die Sie schreiben möchten. Dies geschieht, wenn der Übertragungspuffer des Absenders voll wird, was während eines TCP -Standes passieren kann. Sie könnten Bytes verlieren.

Wenn Sie beispielsweise versuchen, 8192 Bytes mit jedem Anruf zum Schreiben zu schreiben, aber einer der Anrufe zurückgibt 5691, müssen Sie die verbleibenden 2501 Bytes beim nächsten Anruf senden. Andernfalls wird der Client den Rest dieses 8K -Blocks nicht sehen und Ihre Datei ist auf der Clientseite kürzer als auf der Serverseite.

Andere Tipps

Dies geschieht wirklich tief im TCP/IP -Stapel. In Ihrer Anwendung (Server und Client) müssen Sie sich keine Sorgen um TCP Windows machen. Der Fehler muss etwas anderes sein.

Ein TCP -Fenster -Update hat mit der Kommunikation der verfügbaren Puffergröße zwischen dem Absender und dem Empfänger zu tun. Eine ArrayIndexoutOfBoundSexception ist nicht die wahrscheinliche Ursache dafür. Höchstwahrscheinlich erwartet der Code eine Art von Daten, die er nicht erhält (möglicherweise gut vor diesem Punkt, den er erst jetzt bezieht). Ohne den Code und die Stapelspur zu sehen, ist es wirklich schwer, etwas mehr zu sagen.

TCP Windowupdate - Dies zeigt an, dass das Segment ein reines Fenster -Segment war. Ein Windowupdate tritt auf, wenn die Anwendung auf der Empfangsseite bereits aufgenommene Daten aus dem RX -Puffer verbraucht hat, wodurch die TCP -Ebene ein Fensterupdate an die andere Seite gesendet hat, um anzuzeigen, dass jetzt mehr Platz im Puffer verfügbar ist. Normalerweise beobachtet, nachdem ein TCP -Zerowindow -Zustand aufgetreten ist. Sobald die Anwendung auf dem Empfänger Daten aus dem TCP -Puffer abruft und so den Speicherplatz freigibt, sollte der Empfänger den Absender benachrichtigen, dass die TCP -Zerowindow -Bedingung nicht mehr vorhanden ist, indem ein TCP -Fensterupdate gesendet wird, das die aktuelle Fenstergröße bewirbt.

https://wiki.wireshark.org/tcp_analyze_sequence_numbers

Sie können in diese Website eintauchen http://www.tcpipguide.com/free/index.htm Für viele Informationen zu TCP/IP.

Bekommst du welche Einzelheiten mit dem Ausnahme?

Es hängt wahrscheinlich nicht mit dem TCP -Fenster -Update -Paket zusammen
(Haben Sie gesehen, dass es für mehrere Instanzen genau wiederholt wird?)

Wahrscheinlicher ist, dass Sie sich auf Ihren Verarbeitungscode beziehen, der auf den empfangenen Daten funktioniert.

Dies ist normalerweise nur ein Auslöser, nicht die Ursache Ihres Problems.

Wenn Sie beispielsweise NIO Selector verwenden, kann ein Fenster -Update das Aufwachen eines Schreibkanals auslösen. Das wiederum löst die fehlerhafte Logik in Ihrem Code aus.

Holen Sie sich eine Stacktrace und es zeigt Ihnen die Grundursache.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top