oparty na jądrze (Linux) przekaźnik danych między dwoma gniazdami TCP

napisałemSerwer przekazywania TCP który działa jak router typu peer-to-peer (supernode).

Najprostszym przypadkiem są dwa otwarte gniazda i przekazywanie danych między nimi:

clientA <---> serwer <---> klientB

Serwer musi jednak obsługiwać około 2000 takich par A-B, tj. 4000 gniazd ...

Istnieją dwie dobrze znane implementacje przekaźnika strumienia danychobszar użytkownika (oparte nasocketA.recv () -> socketB.send () isocketB.recv () -> socketA.send ()):

korzystanie zWybierz / głosowanie funkcje (metoda nieblokująca)użycie nici / widelców (metoda blokowania)

Użyłem wątków, więc w najgorszym przypadku serwer tworzy 2 * 2000 wątków! Musiałem ograniczyć rozmiar stosu i działa, ale czy jest to właściwe rozwiązanie?

Rdzeń mojego pytania:

Czy istnieje sposób na uniknięcie aktywnego przekazywania danych między dwoma gniazdami w przestrzeni użytkownika?

Wygląda na to, że istnieje pasywny sposób. Na przykład mogę utworzyć deskryptor pliku z każdego gniazda, utworzyć dwie potoki i użyć dup2 () - ta sama metoda jak przekierowanie stdin / out. Następnie dwa wątki są bezużyteczne dla przekaźnika danych i można je zakończyć / zamknąć.Pytanie brzmi, czy serwer powinien kiedykolwiek zamknąć gniazda i rury i wiedzieć, kiedy rura jest zepsuta, aby zarejestrować fakt?

Znalazłem także „pary gniazd”, ale nie jestem tego pewien w moim celu.

Jakie rozwiązanie radziłbyś odciążyć obszar użytkownika i ograniczyć ilość wątków?

Dodatkowe wyjaśnienia:

Serwer zdefiniował statyczną tablicę routingu (np. ID_A z ID_B - identyfikatory sparowane). Klient A łączy się z serwerem i wysyła ID_A. Następnie serwer czeka na klienta B. Po sparowaniu A i B (oba gniazda otwarte) serwer uruchamia przekaźnik danych.Klienci są prostymi urządzeniami za symetrycznym NAT, dlatego protokół N2N lub techniki przejścia NAT są dla nich zbyt skomplikowane.

Dzięki Gerhardowi Riegerowi mam podpowiedź:

Wiem o dwóch sposobach wykorzystania przestrzeni jądra, aby uniknąć odczytu / zapisu, recv / send w przestrzeni użytkownika:

Wyślij pliksplatać

Oba mają ograniczenia dotyczące typu deskryptora pliku.

dup2 nie pomoże zrobić czegoś w jądrze, AFAIK.

Strony man:splot (2) splot (2) vmsplice (2) sendfile (2) tee (2)

Powiązane linki:

Zrozumieć sendfile () i splice ()http://blog.superpat.com/2010/06/01/zero-copy-in-linux-with-sendfile-and-splice/http://yarchive.net/comp/linux/splice.html (Linus)C, różnica sendfile () i send ()?pomost między dwoma deskryptorami plikówWyślij i odbierz plik w programowaniu gniazd w Linuksie z C / C ++ (GCC / G ++)http://ogris.de/howtos/splice.html

questionAnswers(2)

yourAnswerToTheQuestion