Ich übersetze gerade eine API von C # nach Java mit einer Netzwerkkomponente.
Die C # -Version scheint die Eingabe- und Ausgabestreams und den Socket für die Dauer der Verwendung seiner Klassen offen zu halten.
Stimmt das?
Wenn man bedenkt, dass die Anwendung Befehle sendet und Ereignisse basierend auf Benutzereingaben empfängt, ist es sinnvoller, einen neuen Socket-Stream für jede "Nachricht" zu öffnen?
Ich führe einen ServerSocket für das Abhören der Server-Wurf-Events, aber ich bin mir nicht sicher, ob das Aufrechterhalten eines Socket- und Ausgabestreams für ausgehende Kommunikationssignale so eine gute Idee ist.
Ich bin nicht wirklich an die Socket-Programmierung gewöhnt. Wie bei vielen Entwicklern arbeite ich normalerweise auf der Anwendungsebene, wenn ich Networking machen muss und nicht auf der Socket-Ebene, und es sind 5 oder 6 Jahre her, seit ich das Zeug an der Universität gemacht habe.
Prost für die Hilfe. Ich denke, das ist mehr um Rat als um eine endgültige Antwort.
Es besteht ein Kompromiss zwischen den Kosten für das Offenhalten der Verbindungen und den Kosten für die Erstellung dieser Verbindungen.
Verbindungen erstellen kostet Zeit und Bandbreite. Sie müssen den 3-Wege-TCP-Handshake durchführen, einen neuen Server-Thread starten, ...
Verbindungen bleiben offen kostet hauptsächlich Speicher und Verbindungen. Netzwerkverbindungen sind eine vom Betriebssystem begrenzte Ressource. Wenn zu viele Clients verbunden sind, sind möglicherweise nicht mehr genügend Verbindungen verfügbar. Es kostet Speicher, da Sie für jede Verbindung einen Thread mit dem zugehörigen Status geöffnet haben.
Die richtige Balance wird je nach der von Ihnen erwarteten Verwendung unterschiedlich sein. Wenn sich viele Clients für kurze Zeit verbinden, ist es wahrscheinlich effizienter, die Verbindungen zu schließen. Wenn Sie nur wenige Clients haben, die sich für längere Zeit verbinden, sollten Sie die Verbindungen wahrscheinlich offen halten ...
Wenn Sie nur einen einzigen Socket auf dem Client und dem Server haben, sollten Sie ihn so lange wie möglich offen halten.
Wenn Ihre Anwendung und der Server, mit dem Sie sprechen, nah beieinander sind, ist es möglicherweise sinnvoll, die Verbindung zu schließen, aber wenn sie netzwerkweit entfernt sind, ist es wahrscheinlich besser, wenn Sie die Socket für die Dauer.
Guillaume erwähnt den 3-Wege-Handshake und das bedeutet im Grunde, dass das Öffnen eines Sockels mindestens dreimal die kürzeste Paketlaufzeit benötigt. Dies kann durch "die Hälfte des Ping-Round-Trips" approximiert werden und kann leicht 60-100 ms für lange Distanzen erreichen. Wenn sich für jeden Befehl zusätzliche 300 ms Wartezeit ergeben, wird sich dies auf die Benutzererfahrung auswirken?
Persönlich würde ich den Sockel offen lassen, es ist einfacher und kostet keine Zeit für jede Instanz von "muss etwas senden", die relativen Kosten sind gering (ein Dateideskriptor, ein bisschen Speicher für die Datenstrukturen in User-Space und etwas zusätzlichen Speicher im Kernel).
Es hängt davon ab, wie häufig Sie erwarten, dass der Benutzer Befehle eingibt. Wenn es ziemlich selten passiert, könnten Sie vielleicht die Steckdosen schließen. Wenn häufig, kann das Erstellen von Sockets eine teure Operation sein.
Nun, wie teuer ist es in Bezug auf die Maschinenressourcen, eine Socket-Verbindung für seltene Daten offen zu haben? Warum genau denkst du, dass "das Aufrechterhalten eines Sockets und Ausgabestroms für ausgehende Kommunikation nicht so eine gute Idee ist" (obwohl es das Richtige zu tun scheint)? Auf der anderen Seite ist dies für Dateiströme anders, wenn Sie erwarten, dass andere Prozesse die gleiche Datei verwenden möchten. Das Schließen des Dateistroms wäre in diesem Fall der richtige Weg.
Wie wahrscheinlich ist es, dass Ihnen die vielen TCP-Verbindungen, die Sie erstellen können, ausgehen, die andere Prozesse, die ausgehende Verbindungen verwenden möchten, vielleicht verwenden möchten? Oder erwarten Sie, dass sich eine große Anzahl von Clients gleichzeitig mit Ihrem Server verbindet?
Ich schlage vor, dass Sie eine vorhandene Messaging-Lösung wie ActiveMQ oder Netty verwenden. Dies wird viele Probleme behandeln, die Sie mit Messaging finden können.
Ich komme ein bisschen spät, aber ich habe niemanden gesehen, der das vorgeschlagen hat.
Ich denke, es ist ratsam, in Betracht zu ziehen, Ihre Verbindungen zu bündeln (egal, ob Socket oder TCP), die paar Verbindungen offen zu halten und sie schnell in Ihrer Codebasis wiederzuverwenden wäre im Falle der Leistung optimal.
Tatsächlich verwendet der Roslyn-Compiler diese Technik häufig an vielen Orten. Ссылка
Tags und Links java network-programming