Как я могу "соединить" два сокета в Linux? - PullRequest
10 голосов
/ 20 апреля 2010

Есть две соединенные розетки. Как я могу их соединить?

  1. Данные, появившиеся на одном сокете, должны быть записаны на другом.
  2. EOF / FIN должен хорошо распространяться. Если один полузакрыт, другой также должен быть полузакрыт.
int client = get_connected_client_socket();
int proxy = get_connected_proxy_socket();
negotiate_with_proxy(proxy);
iterconnect(client, proxy); 
// Now forgot about both client and proxy. 
// System should handle IO/shutdown/close. 
// Ideally even without any support of the user-space process.

Может ли Linux это сделать? Можно ли сделать это путем отслеживания соединения, чтобы изменить статус отслеживания существующего соединения?

@ related Определите, сколько я могу записать в дескриптор файла; копирование данных с одного FH на другой

Ответы [ 4 ]

4 голосов
/ 20 апреля 2010

Вам известно о сращивании () . Исходя из ваших двух вопросов, я думаю вот куда вы направляетесь. В последний раз я проверял, что вы не можете сделать это за один вызов соединения, потому что оба файловых дескриптора не могут быть сокетами. Но вы должны быть в состоянии сделать это за 2 вызова (sockin-> pipe-> sockout). Также взгляните на тройник () . Это может быть не совсем то, что вы хотите, но, насколько я могу судить, они находятся на стадионе.

2 голосов
/ 21 апреля 2010

Вам понадобится процесс пользовательского пространства, чтобы торчать и копировать данные из одного сокета в другой. Это довольно просто:

  • Любые данные read от розетки A, write до розетки B;
  • Любые данные read от розетки B, write до розетки A;
  • Если read возвращает 0 для сокета A, вызовите shutdown(SHUT_WR) для сокета B;
  • Если read возвращает 0 в сокете B, вызовите shutdown(SHUT_WR) в сокете A;
  • Как только оба сокета вернули 0 из чтения, close оба сокета и выход;
  • Если один из сокетов возвращает EPIPE, close оба сокета и выход.

Как упоминает Newton Falls , вы можете использовать splice(), чтобы сделать это без копирования, но это всего лишь повышение производительности; сначала запустите read / write. Вы должны быть в состоянии просто fork() отучить ребенка, чтобы сделать это, что заставит его «выстрелить и забыть» для вашего основного процесса.

0 голосов
/ 24 августа 2012

Оформить заказ инструментом socat. Это лучший инструмент для решения подобных проблем.

0 голосов
/ 20 апреля 2010

Может помочь сокет домена unix.Смотрите справочную страницу:

man unix
...