ядро (Linux) для передачи данных между двумя сокетами TCP

я написалСервер ретрансляции TCP который работает как одноранговый маршрутизатор (суперузел).

Самый простой случай - это два открытых сокета и передача данных между ними:

clientA <---> сервер <---> clientB

Однако сервер должен обслуживать около 2000 таких пар A-B, т.е. 4000 розеток ...

Есть две хорошо известные реализации ретрансляции потока данных впользовательские программы (на основеsocketA.recv () -> socketB.send () а такжеsocketB.recv () -> socketA.send ()):

использованиеВыбрать / опрос функции (неблокирующий метод)использование нитей / вилок (метод блокировки)

Я использовал потоки, поэтому в худшем случае сервер создает потоки 2 * 2000! Я должен был ограничить размер стека, и это работает, но это правильное решение?

Суть моего вопроса:

Есть ли способ избежать активной передачи данных между двумя сокетами в пользовательском пространстве?

Кажется, есть пассивный путь. Например, я могу создать дескриптор файла из каждого сокета, создать два канала и использовать dup2 () - такой же метод, как перенаправление stdin / out. Тогда два потока бесполезны для передачи данных и могут быть закончены / закрыты.Вопрос в том, должен ли сервер когда-либо закрывать сокеты и каналы и как узнать, когда канал разорван, чтобы зарегистрировать факт?

Я также нашел «пары розеток», но я не уверен в этом для своих целей.

Какое решение вы бы посоветовали разгрузить пользовательское пространство и ограничить количество потоков?

Некоторые дополнительные объяснения:

Сервер определил статическую таблицу маршрутизации (например, ID_A с ID_B - парные идентификаторы). Клиент A подключается к серверу и отправляет ID_A. Затем сервер ожидает клиента B. Когда A и B сопряжены (оба сокета открыты), сервер запускает ретрансляцию данных.Клиенты являются простыми устройствами за симметричным NAT, поэтому протокол N2N или методы обхода NAT слишком сложны для них.

Благодаря Герхарду Ригеру у меня есть подсказка:

Я знаю о двух способах пространства ядра, чтобы избежать чтения / записи, recv / send в пространстве пользователя:

послать файлсращивание

Оба имеют ограничения относительно типа файлового дескриптора.

dup2 не поможет что-то сделать в ядре, AFAIK.

Справочные страницы:сращивания (2) сращивания (2) vmsplice (2) SendFile (2) тройник (2)

Ссылки по теме:

Понимание sendfile () и splice ()http://blog.superpat.com/2010/06/01/zero-copy-in-linux-with-sendfile-and-splice/http://yarchive.net/comp/linux/splice.html (Линус)C, sendfile () и send () разница?мост между двумя файловыми дескрипторамиОтправка и получение файла при программировании сокетов в Linux с использованием C / C ++ (GCC / G ++)http://ogris.de/howtos/splice.html

Ответы на вопрос(2)

Ваш ответ на вопрос