Как узнать, находится ли сокет в неблокирующем режиме в Windows? - PullRequest
5 голосов
/ 20 октября 2010

Есть ли способ узнать, находится ли сокет в неблокирующем режиме в Windows?

Я знаю, что это можно сделать в случае Linux, но я не могу найти какой-либо способ дляэто Windows.

Вся моя кодировка написана на языке 'C'.Есть ли способ?

Ответы [ 3 ]

4 голосов
/ 20 октября 2010

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

Сокет будет блокироваться, если вы явно не установите его неблокирующим с помощью WSAIoctl или ioctlsocket с FIONBIO.Это не может быть слишком сложно, чтобы проверить в своем коде, я бы подумал.Если вам нужно отследить это во время выполнения, то вам нужно выбрать флаг для каждого сокета, предложенный @jweyrich.

1 голос
/ 12 октября 2015

Только что ответил на тот же вопрос здесь , так что вот копия-паста в надежде, что это поможет:

Раньше вы могли вызвать WSAIsBlocking , чтобы определить это. Если вы управляете унаследованным кодом, это все еще может быть вариантом.

В противном случае вы можете написать простой слой абстракции поверх API сокета. Поскольку все сокеты по умолчанию блокируются, вы можете сохранить внутренний флаг и принудительно выполнить все операции сокетов через API, чтобы всегда знать состояние.

Вот кроссплатформенный фрагмент кода для установки / получения режима блокировки, хотя он не работает точно так, как вы хотите в Windows:

/// @author Stephen Dunn
/// @date 10/12/15
bool set_blocking_mode(const int &socket, bool is_blocking)
{
    bool ret = true;

#ifdef WIN32
    /// @note windows sockets are created in blocking mode by default
    // currently on windows, there is no easy way to obtain the socket's current blocking mode since WSAIsBlocking was deprecated
    u_long flags = is_blocking ? 0 : 1;
    ret = NO_ERROR == ioctlsocket(socket, FIONBIO, &flags);
#else
    const int flags = fcntl(socket, F_GETFL, 0);
    if ((flags & O_NONBLOCK) && !is_blocking) { info("set_blocking_mode(): socket was already in non-blocking mode"); return ret; }
    if (!(flags & O_NONBLOCK) && is_blocking) { info("set_blocking_mode(): socket was already in blocking mode"); return ret; }
    ret = 0 == fcntl(socket, F_SETFL, is_blocking ? flags ^ O_NONBLOCK : flags | O_NONBLOCK);
#endif

    return ret;
}
0 голосов
/ 20 октября 2010

Из MSDN возвращаемое значение connect () :

  • В блокирующем сокете возвращаемое значение указывает на успех или неудачу попытки подключения.

  • При использовании неблокирующего разъема попытка подключения не может быть немедленно завершена. В этом случае connect вернет SOCKET_ERROR, а WSAGetLastError() вернет WSAEWOULDBLOCK .

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