Frage

Ich suche nach Strategien, die Menschen bei der Implementierung von Serveranwendungen verwenden, die Client-TCP- (oder UDP-)Anfragen bedienen:Entwurfsmuster, Implementierungstechniken, Best Practices usw.

Nehmen wir für diese Frage an, dass die Anfragen relativ langlebig sind (mehrere Minuten) und dass der Datenverkehr zeitkritisch ist, sodass Verzögerungen bei der Beantwortung von Nachrichten nicht akzeptabel sind.Außerdem bearbeiten wir sowohl Anfragen von Kunden als auch stellen unsere eigenen Verbindungen zu anderen Servern her.

Meine Plattform ist .NET, aber da die zugrunde liegende Technologie unabhängig von der Plattform dieselbe ist, bin ich an Antworten für jede Sprache interessiert.

War es hilfreich?

Lösung

Der moderne Ansatz besteht darin, das Betriebssystem zu nutzen, um viele Netzwerk-Sockets für Sie zu multiplexen, sodass Ihre Anwendung nur aktive Verbindungen mit Datenverkehr verarbeiten muss.

Immer wenn Sie einen Socket öffnen, wird er mit einem Selektor verknüpft.Sie verwenden einen einzelnen Thread, um diesen Selektor abzufragen.Immer wenn Daten eintreffen, zeigt der Selektor den aktiven Socket an. Sie übergeben diesen Vorgang an einen untergeordneten Thread und fahren mit der Abfrage fort.

Auf diese Weise benötigen Sie nur einen Thread für jede gleichzeitige Operation.Offene, aber inaktive Sockets binden keinen Thread.

Andere Tipps

Ein ausgefeilterer Ansatz wäre die Verwendung von IO Completion-Ports.(Windows) Mit E/A-Abschluss-Ports überlassen Sie es dem Betriebssystem, die Abfrage zu verwalten, wodurch es potenziell ein sehr hohes Maß an Optimierung mit NIC-Treiberunterstützung verwenden kann.Grundsätzlich verfügen Sie über eine Warteschlange mit Netzwerkvorgängen, die vom Betriebssystem verwaltet wird, und stellen eine Rückruffunktion bereit, die aufgerufen wird, wenn der Vorgang abgeschlossen ist.Ein bisschen wie (Festplatten-)DMA, aber für das Netzwerk.

Len Holgate hat vor einigen Jahren auf Codeproject eine hervorragende Serie über IO-Completion-Ports geschrieben:http://www.codeproject.com/KB/IP/jbsocketserver2.aspx

Und Ich habe einen Artikel über E/A-Vervollständigungsports für .net gefunden (habe ihn aber nicht gelesen) http://www.codeproject.com/KB/cs/managediocp.aspx

Ich würde auch sagen, dass es einfacher ist, Vervollständigungsports zu verwenden, als zu versuchen, eine skalierbare Alternative zu schreiben.Das Problem ist, dass sie nur auf NT (2000, XP, Vista) verfügbar sind.

Wenn Sie C++ und Win32 direkt verwenden, empfehle ich Ihnen, sich über überlappende I/O- und I/O-Completion-Ports zu informieren.Ich habe ein kostenloses C++-, IOCP-, Client/Server-Framework mit vollständigem Quellcode, siehe Hier für mehr Details.

Da Sie .Net verwenden, sollten Sie die Verwendung der asynchronen Socket-Methoden in Betracht ziehen, damit Sie nicht für jede Verbindung einen Thread benötigen.Es gibt mehrere Links aus diesem Blogeintrag von mir, die nützliche Ausgangspunkte sein könnten: http://www.lenholgate.com/blog/2005/07/disappointing-net-sockets-article-in-msdn-magazine-this-month.html (Einige der besten Links finden Sie in den Kommentaren zum Originalbeitrag!)

Tag auch,

Ich würde damit beginnen, mir die Metapher anzusehen, die Sie für Ihr Thread-Framework verwenden möchten.

Vielleicht ein „Leader-Follower“, bei dem ein Thread auf eingehende Anfragen lauscht und wenn eine neue Anfrage eingeht, erledigt er die Arbeit und der nächste Thread im Pool beginnt, auf eingehende Anfragen zu lauschen.

Oder Thread-Pool, bei dem immer derselbe Thread auf eingehende Anfragen wartet und die Anfragen dann an den nächsten verfügbaren Thread im Thread-Pool weiterleitet.

Vielleicht möchten Sie die besuchen Reaktor Sehen Sie sich den Abschnitt „Ace Components“ an, um einige Ideen zu erhalten.

HTH.

Prost Rauben

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