Программирование на C++ глазами хакера


. Прием и передача данных - часть 2


int ioctisocket ( SOCKET s, long cmd, u_long FAR* argp );

У этой функции три параметра:

  • сокет, режим которого надо изменить;
  • команда, которую необходимо выполнить;
  • параметр для команды.

Изменение режима блокирования происходит при указании в качестве команды константы FIONBIO. При этом, если параметр команды имеет нулевое значение, то будет использоваться блокирующий режим, иначе — неблокирующий.

Давайте посмотрим на пример создания сокета и перевода его в неблокирующий режим:

SOCKET s; unsigned long ulMode;

s = socket(AS_INET, SOCK_STREAM, 0); ulMode = 1; ioctisocket(s, FIONBIO, (unsigned long*)&ulMode);

Теперь все функции приема/передачи будут завершаться ошибкой. Это нормальная реакция, и вы должны это учитывать при создании сетевых приложений, работающих в неблокирующем режиме. Если функция ввода/вывода вернула ошибку WSAEWOULDBLOCK, то это не означает неправильную передачу. Все прошло успешно, просто используется неблокирующий режим. Если же действительно произошел сбой, то мы получим ошибку, отличную от WSAEWOULDBLOCK.

В неблокирующем режиме функция recv не будет дожидаться приема данных, а просто вернет ошибку WSAEWOULDBLOCK. Тогда как нам узнать, что данные поступили на порт? Некоторые запускают цикл с постоянным вызовом функции recv, пока она не вернет данные. Но это нецелесообразно, потому что происходит блокирование приложения и излишне загружается процессор.

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




Начало  Назад  Вперед



Книжный магазин