Неблокирующие сокеты требуются для прокси? - PullRequest
1 голос
/ 27 августа 2011

У меня есть следующий код:

 {                                
     send(dstSocket, rcvBuffer, recvMsgSize, 0);
     sndMsgSize = recv(dstSocket, sndBuffer, RCVBUFSIZE, 0);
     send(rcvSocket, sndBuffer, sndMsgSize, 0);           
     recvMsgSize = recv(rcvSocket, rcvBuffer, RCVBUFSIZE, 0);
 }

, который в конечном итоге должен стать частью общего TCP-прокси. Теперь он работает не совсем корректно, так как recv () ожидает ввода, поэтому данные передаются только кусками, в зависимости от того, где они находятся в данный момент.

Что я прочитал, так это то, что мне нужно что-то вроде «неблокирующих сокетов» и механизма для их мониторинга. Этот механизм, как я выяснил, в Linux - это выбор, опрос или epoll. Может ли кто-нибудь дать мне подтверждение, что я на правильном пути? Или это упражнение можно выполнить и с помощью блокирующих розеток?

С уважением

Ответы [ 3 ]

1 голос
/ 27 августа 2011

Вы находитесь на правильном пути.

«выбор» и «опрос» - это системные вызовы, в которых вы можете передавать один или несколько сокетов и блокировать (в течение определенного периода времени) до получения данных.(или готов к отправке) на одном из этих сокетов.

«неблокирующие сокеты» - это настройка, которую вы можете применить к сокету (или флагу вызова recv), например, если вы попытаетесь вызвать recv, ноданные недоступны, звонок перезвонит немедленно.Подобная семантика существует для «send».Вы можете использовать неблокирующие сокеты с или без метода выбора / опроса, описанного выше.Обычно неплохо использовать неблокирующие операции на тот случай, если вам сообщат о данных, которых там нет.

«epoll» - это масштабируемая версия выбора и опроса.Набор "select" на самом деле ограничен чем-то вроде 64-256 сокетов для мониторинга за один раз, и он требует точного удара, когда количество отслеживаемых сокетов увеличивается.«epoll» может масштабировать до тысяч одновременных сетевых подключений.

0 голосов
/ 27 августа 2011

Да, вам придется использовать один из этих механизмов. Опрос портативный и IMO самый простой в использовании. В этом случае вам не нужно отключать блокировку, если вы используете достаточно малое значение для RCVBUFSIZE (должно быть около 2k-10k). Неблокирующие сокеты немного сложнее обрабатывать, так как если вы получаете EAGAIN при отправке, вы не можете просто зацикливаться, чтобы повторить попытку (хорошо, но не следует, так как он использует ЦП без необходимости).

Но я бы порекомендовал использовать обертку, такую ​​как libevent. В этом случае struct bufferevent будет работать особенно хорошо. Он сделает обратный вызов, когда появятся новые данные, и вы просто поставите их в очередь для отправки на другой сокет.

Пытался найти хороший пример, но, похоже, его немного не хватает. В любом случае документация здесь: http://monkey.org/~provos/libevent/doxygen-2.0.1/index.html

0 голосов
/ 27 августа 2011

Да, вы на правильном пути. Используйте неблокирующий сокет, передавая их относительные файловые дескрипторы для выбора (см. FD_SET ()).

Этот способ выбора будет отслеживать события (чтение / запись) на них.

Когда возвращается select, вы можете проверить, на каком fd произошло событие (посмотрите на FD_ISSET ()) и обработать его.

Вы также можете установить тайм-аут при выборе, и он вернется после этого периода, даже если события не произошли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...