3 Stimmen

Behandlung mehrerer TcpClient-Verbindungen ohne Verwendung von Threads

Ich habe ein C#-Programm mit vielen (sagen wir etwa tausend) geöffneten TcpClient-Objekten. Ich möchte einen Zustand eingeben, die für etwas warten, um für jede dieser Verbindungen geschehen wird.

Ich würde lieber nicht für jede Verbindung einen eigenen Thread starten.

Etwas wie...

while (keepRunning)
{
     // Wait for any one connection to receive something.
     TcpClient active = WaitAnyTcpClient(collectionOfOpenTcpClients);

     // One selected connection has incomming traffic. Deal with it.
     // (If other connections have traffic during this function, the OS
     // will have to buffer the data until the loop goes round again.)
     DealWithConnection(active);
}

Zusätzliche Informationen:
Die TcpClient-Objekte stammen von einem TcpListener.
Die Zielumgebung wird MS .NET oder Mono-on-Linux sein.
Das Protokoll sieht lange Leerlaufzeiten vor, während die Verbindung offen ist.

2voto

Krit Punkte 538

Was Sie hier versuchen, wird in der Microsoft-Terminologie als Async-Pattern bezeichnet. Die Grundidee besteht darin, alle blockierenden E/A-Operationen in nicht blockierende Operationen umzuwandeln. Wenn dies geschieht, benötigt die Anwendung in der Regel so viele System-Threads, wie es CPU-Kerne auf dem Rechner gibt.

Werfen Sie einen Blick auf Task Parallel Library in .Net 4: http://msdn.microsoft.com/en-us/library/dd460717%28VS.100%29.aspx

Es ist ein ziemlich ausgereifter Wrapper über das einfache alte Begin/Callback/Context .Net-Paradigma.

Aktualisierung:

Überlegen Sie sich, was Sie mit den Daten machen wollen, nachdem Sie die Verbindung ausgelesen haben. Im wirklichen Leben müssen Sie wahrscheinlich dem Client antworten oder die Daten in einer Datei speichern. In diesem Fall benötigen Sie eine C#-Infrastruktur, um Ihre Logik einzuschließen/zu verwalten und trotzdem in einem einzigen Thread zu bleiben. TPL stellt sie Ihnen kostenlos zur Verfügung. Der einzige Nachteil ist, dass es in .Net 4 eingeführt wurde, also ist es wahrscheinlich noch nicht in Mono.

Ein weiterer Punkt ist die Lebensdauer der Verbindung. Wie oft werden Ihre Verbindungen geöffnet/geschlossen und wie lange leben sie? Dies ist wichtig, weil das Annehmen und Trennen einer TCP-Verbindung den Austausch von Paketen mit dem Client erfordert (was von Natur aus asynchron ist, und darüber hinaus - ein böswilliger Client könnte überhaupt keine ACK(-bestätigten) Pakete zurücksenden). Wenn Sie der Meinung sind, dass dieser Aspekt für Ihre Anwendung von Bedeutung ist, sollten Sie nachforschen, wie Sie dies in .Net richtig handhaben können. In WinAPI sind die entsprechenden Funktionen AcceptEx und DisconnectEx. Wahrscheinlich sind sie in .Net mit Begin/End-Methoden verpackt - in diesem Fall sind Sie startklar. Andernfalls müssen Sie wahrscheinlich einen Wrapper über diese WinAPI-Aufrufe erstellen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X