Winsock2: функция select (), выдающая «недопустимая ошибка аргумента» (ошибка 10022)? - PullRequest
1 голос
/ 29 мая 2019

Запуск функции select () (строка 13 предоставленного кода) возвращает ошибку 10022 (WSAEINVAL), означающую, что либо моя переменная тайм-аута в отрицательной, либо все 3 другие переменные равны NULL.Но я получаю эту ошибку только после первой итерации по внешнему циклу.

По сути, моя установка состоит в том, чтобы отправить окно пакетов размера N на базе, а затем проверить, было ли мне отправлено какое-либо подтверждениепроверив, готов ли мой сокет читать из.Для первого окна пакетов вызов select () работает нормально, возвращая 1. Но все вызовы select () после первой итерации полного цикла приводят к коду ошибки.У меня совершенно нет идей.

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

int Exit = 0;
int endRecv = 0;
int ready = 0;
//Sending Algorithm
int base = 0;
uint32_t confirmedPosition;



while (Exit == 0) {
    //Send data in an N sized Window.
    for (int i = 0; i < N; i++) {
        if (successfulPackets[i + base] != 1) {
            memcpy(&buffer_tx, &packets[i + base], BUFFERS_LEN);
            sendto(socketS, buffer_tx, BUFFERS_LEN, 0, (sockaddr*)& addrDest, sizeof(addrDest));
        }
    }
    endRecv = 0;
    //Receive Confirmations
    while (endRecv == 0) {
        //Poll to see if something is waiting
        ready = select(NULL, &readfds, NULL, NULL, &pollTime);
        if (ready == -1) {
            printf("Error with Code: %d", WSAGetLastError());
        } else if (ready == 1) {//If yes, log confirmation
            recvfrom(socketS, buffer_rx, BUFFERS_LEN, 0, (sockaddr *)&from, &fromlen);
            memcpy(&confirmedPosition, &buffer_rx, 4);
            successfulPackets[confirmedPosition] = 1;
            fileSize -= BUFFERS_LEN - 8;
        } else {//If no, end receiving and send
            endRecv = 1;
        }
    }
    //Apply Changes to Base
    for (int i = 0; i < N; i++) {
        if (successfulPackets[base] == 1) {
            base++;
        }
    }
    if (fileSize <= 0) {
        Exit = 1;
    }
}

1 Ответ

1 голос
/ 29 мая 2019

Когда select возвращает 0, тогда содержимое структуры readfds также устанавливается на ноль (select изменяет его, чтобы указать, какой сокет готов).

Когда внешний цикл выполняется снова, структура readfds не содержитлюбой сокет для проверки, который вызывает ошибку.Вы должны снова установить сокет в readfds.

...