ядро (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