Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > WSAENOTSOCK в select


Автор: Bargest 6.2.2015, 23:48
Пытаюсь подключить клиента и сразу же проверить наличие данных для приема:
Код

    SOCKET sc = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    sockaddr_in sa;
    sa.sin_addr.s_addr = INADDR_ANY;
    sa.sin_port = htons(23946);
    sa.sin_family = AF_INET;
    int res = bind((SOCKET)sc, (sockaddr *)&sa, (int)sizeof(sockaddr_in));
    listen(sc, SOMAXCONN);
    sock = accept(sc, NULL, NULL);
    u_long mode = 1;
    ioctlsocket(sock, FIONBIO, &mode);
    timeval t = { 0, 0 };
    fd_set read_fd;
    FD_ZERO(&read_fd);
    FD_SET(sock, &read_fd);
    if (select(0, &read_fd, 0, 0, &t) == SOCKET_ERROR)
    {
        int err = WSAGetLastError();
        return ;
    }

И select выдает SOCKET_ERROR, код ошибки - WSAENOTSOCK ("не сокет"). MSDN говорит, что select возвращает эту ошибку, если в структуре fd_set одно из полей не является сокетом.
При этом если я не использую select, а просто принимаю данные:
Код

int size = recv(sock, (char*)buf, 512, 0);

То данные благополучно приходят.
Пробовал делать ожидание после accept'а, пробовал делать в блокирующем режиме (с NULL вместо таймаута) - результат один и тот же.
Изначально эта проверка select'ом делалась в другом месте, но сейчас в поисках баги я уже перенес эту проверку вплотную к accept'у. И все равно получаю этот WSAENOTSOCK.
Что тут не так?

Автор: feodorv 7.2.2015, 04:41
Цитата(Bargest @  6.2.2015,  23:48 Найти цитируемый пост)
Что тут не так?

На вид все так, только Вы не проверили, что sock не равен INVALID_SOCKET. Но раз
Цитата(Bargest @  6.2.2015,  23:48 Найти цитируемый пост)
если я не использую select, а просто принимаю данные
работает, то сокет, вроде рабочий. А какой тип у переменной sock?

Автор: feodorv 7.2.2015, 04:56
Цитата(Bargest @  6.2.2015,  23:48 Найти цитируемый пост)
    SOCKET sc = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

Может, вместо IPPROTO_IP тупо 0 поставить?

Автор: Bargest 7.2.2015, 13:11
Цитата
что sock не равен INVALID_SOCKET

В дебаге проверял, там 0x68. Вполне нормальный сокет.
Цитата
А какой тип у переменной sock? 

Код

SOCKET sock;

Цитата
Может, вместо IPPROTO_IP тупо 0 поставить? 

Код

// из ws2def.h
#define IPPROTO_IP              0

В общем, так и не поняв, в чем была проблема, переделал на WSAEventSelect + WaitForSingleObject и стало нормально.
Вопрос более не актуален.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)