"Die Anwendung läuft seit Jahren einwandfrei, letzte Woche wurde das Netzwerk aufgerüstet und wir wechselten von 100 mbps auf Gigabit. Jetzt ist die letzte Hälfte der Daten in einigen Nachrichten Müll. Die Netzwerkleute schwören, dass es nicht am Netzwerk liegt - aber das ist das einzige, was sich geändert hat."
Die gute Nachricht ist, dass das teure Netzwerk-Upgrade die Anwendung nicht zerstört hat.
Die schlechte Nachricht ist, dass die Anwendung kaputt ist und schon immer kaputt war. Was *viele* Leute, die TCP-Anwendungen schreiben, nicht wissen, ist, dass TCP ein Strom von Bytes ist, nicht von Nachrichten. Die Tatsache, dass eine Anwendung zwei 1000-Byte-Nachrichten sendet, bedeutet nicht, dass der sendende TCP-Stack zwei 1000-Byte-TCP-Segmente senden wird. Die Anwendungsnachrichten können in kleinere Segmente aufgeteilt werden, die entweder auf der vom Empfänger angegebenen maximalen Segmentgröße oder auf einer Konfigurationsbeschränkung des Senders basieren. Auch bei der erneuten Übertragung können Anwendungsnachrichten kombiniert und fragmentiert werden. Selbst wenn der sendende TCP-Stack tatsächlich zwei 1000-Byte-TCP-Segmente sendet, gibt es keine Garantie, dass der empfangende TCP-Stack der empfangenden Anwendung zwei 1000-Byte-Nachrichten liefert. Wenn der Puffer der Anwendung zum Beispiel nur 500 Byte groß ist, ist das alles, was der TCP-Stack zurückgibt. Ist der Puffer hingegen 1500 Byte groß und sind beide 1000-Byte-Segmente eingetroffen, wird der TCP-Stack beim ersten Aufruf 1500 Byte und beim zweiten Aufruf 500 Byte zurückgeben. Es liegt an der Anwendung, den Bytestrom zu nehmen und ihn korrekt in Nachrichten zu zerlegen.
Was hat das mit der Aufrüstung des Netzwerks zu tun? Nun, der OpenVOS-Server und der Linux-Client befanden sich in verschiedenen Subnetzen, so dass das OpenVos-System eine maximale Segmentgröße von 536 Byte anzeigte. Die vom Client gesendeten Anwendungsnachrichten hatten eine Größe von 1000 Bytes, so dass die Nachrichten in 2 Teile segmentiert wurden. Vor dem Upgrade trafen beide Segmente beim OpenVOS-Server ein, bevor die Anwendung ihren Empfang sendete, so dass alle 1000 Bytes mit einem Aufruf der Empfangsfunktion gelesen wurden. Nach dem Upgrade änderte sich das Timing der Segmente, so dass manchmal nur das erste Segment verfügbar war, wenn die Anwendung ihren Empfangsbefehl gab. Die letzten 464 (1000 - 536) Bytes des Anwendungspuffers wurden nicht vom TCP-Stack aufgefüllt und enthielten den Müll, der vor dem Empfang vorhanden war.
In diesem Fall gab es eine einfache, schnelle Lösung: Erhöhen Sie den von OpenVOS beworbenen MSS-Wert auf 1460 (siehe Ein einfacher Weg zur Verbesserung des TCP-Durchsatzes über Subnetze). Das ist jedoch nur eine Notlösung. Die wirkliche Lösung besteht darin, den Code umzuschreiben, um den TCP-Byte-Strom korrekt in Anwendungsnachrichten zu zerlegen, anstatt einfach davon auszugehen, dass ein Empfangsaufruf eine Nachricht zurückgibt.