maaGames
@maaGames
Погроммирую программы

Корректное использование poll recv?

В прошлый раз ответы сообщества мне очень помогли, ещё раз большое всем спасибо. Прога заработала и в локальной сети и через интернет.
У меня новый вопрос.

Вот я создаю сокетное соединение, accept'ом получаю парный сокет и могу туда-сюда байтики кидать.
После этого делаю poll, ожидая данные.
После этого в цикле читаю данные функцией recv и... цикл закрывается только после закрытия парного сокета. Т.е. я не знаю, сколько объектов и с какой периодичностью приходят в сокет. Сами объекты десериализируются без проблем, но я не знаю, есть ли ещё в буфере что-то и когда прилетит следующий объект (и прилетит ли он).
Т.е. получается, что один раз вызывается accept для установки соединения, один раз взывается poll, а потом "вечно" в цикле вызывается recv и висит в этой функции, пока не придёт сообщение.
Мне кажется, что я что-то делаю не правильно, потому что не ясен смысл метода poll (или он только для передачи первых байт нужен, после установки соединения, а потом можно и без него обходиться?). Соединение может оставаться установленным от пары секунд, до нескольких суток (смотря с чем приходится работать), при этом поток будет висеть в функции recv в ожидании следующего объекта, которого может и не быть в принципе. При этом в обратном направлении за это время передаются десятки тысяч объектов (независимо от общего времени работы).
Использую блокирующий сокет, неблокирующий пока что не удалось правильно использовать.

ПСЕВДОКОД
socket  = accept;
if( poll( socket ) )
{
      while( recv(....) > 0 )
     {
            ... ;
     }
}
  • Вопрос задан
  • 331 просмотр
Пригласить эксперта
Ответы на вопрос 1
@res2001
Developer, ex-admin
Вы не правильно понимаете.
При таком использовании как сейчас у вас смысла в poll особого нет, а так же нет особого смысла использовать его в блокирующем режиме сокета, т.к. в этом режиме recv (send) не вернет управление пока не сделает свою работу или пока не возникнет ошибка или пока не придет сигнал.

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

poll вам возвращает признак есть ли в сокете данные для чтения (или готов ли он к записи). Если да - вызываете recv (send), если нет можно поделать что-то свое, потом снова вызвать poll.

Кроме того имейте ввиду, что recv может получить не полный буфер, и send отправить не весь буфер.

Всегда анализируйте возвращаемые значения системных функций, особенно когда дело касается ввода/вывода.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы