Kernel-basiertes (Linux) Daten-Relay zwischen zwei TCP-Sockets

Ich hab geschriebenTCP-Relay-Server Das funktioniert wie ein Peer-to-Peer-Router (Supernode).

Der einfachste Fall sind zwei geöffnete Steckdosen und Datenrelais zwischen ihnen:

clientA <---> server <---> clientB

Der Server muss jedoch ungefähr 2000 solcher A-B-Paare bedienen, d.h. 4000 Steckdosen ...

Es gibt zwei bekannte Datenstrom-Relais-Implementierungen inuserland (beyogen aufsocketA.recv () -> socketB.send () undsocketB.recv () -> socketA.send ()):

Verwendung vonwählen / Umfrage Funktionen (nicht blockierende Methode)Verwendung von Gewinden / Gabeln (Blockiermethode)

Ich habe Threads verwendet, sodass der Server im schlimmsten Fall 2 * 2000 Threads erstellt! Ich musste die Stapelgröße begrenzen und es funktioniert, aber ist es die richtige Lösung?

Kern meiner Frage:

Gibt es eine Möglichkeit, die Weitergabe aktiver Daten zwischen zwei Sockets im Benutzerland zu vermeiden?

Es scheint einen passiven Weg zu geben. Zum Beispiel kann ich von jedem Socket einen Dateideskriptor erstellen, zwei Pipes erstellen und dup2 () verwenden - die gleiche Methode wie die Umleitung von stdin / out. Dann sind zwei Threads für die Datenweitergabe unbrauchbar und können beendet / geschlossen werden.Die Frage ist, ob der Server jemals Sockets und Pipes schließen sollte und wie man weiß, wann die Pipes defekt sind, um die Tatsache zu protokollieren.

Ich habe auch "Socket-Paare" gefunden, bin mir aber nicht sicher, ob ich das für meinen Zweck tun soll.

Welche Lösung würden Sie empfehlen, um das Userland zu entladen und die Anzahl der Threads zu begrenzen?

Einige zusätzliche Erklärungen:

Der Server hat eine statische Routingtabelle definiert (z. B. ID_A mit ID_B - gepaarten Bezeichnern). Client A stellt eine Verbindung zum Server her und sendet ID_A. Dann wartet der Server auf Client B. Wenn A und B gekoppelt sind (beide Sockets geöffnet), startet der Server das Datenrelay.Clients sind einfache Geräte hinter symmetrischem NAT, daher sind N2N-Protokoll- oder NAT-Traversal-Techniken für sie zu komplex.

Dank Gerhard Rieger habe ich den Tipp:

Ich kenne zwei Möglichkeiten im Kernel-Space, um das Lesen / Schreiben, Empfangen / Senden im User-Space zu vermeiden:

Datei sendenspleißen

Beide haben Einschränkungen hinsichtlich des Typs des Dateideskriptors.

dup2 wird nicht helfen, etwas im Kernel zu tun, AFAIK.

Manpages:Spleiß (2) Spleiß (2) vmsplice (2) sendfile (2) T-Stück (2)

Ähnliche Links:

Sendfile () und splice () verstehenhttp://blog.superpat.com/2010/06/01/zero-copy-in-linux-with-sendfile-and-splice/http://yarchive.net/comp/linux/splice.html (Linus)C, Unterschied zwischen sendfile () und send ()?Überbrückung zwischen zwei DateideskriptorenSenden und Empfangen einer Datei in der Socket-Programmierung unter Linux mit C / C ++ (GCC / G ++)http://ogris.de/howtos/splice.html

Antworten auf die Frage(2)

Ihre Antwort auf die Frage