Как решить проблемы, связанные с ошибками Winsock 10054 и 10053?

При отправке файла размером 1,34 МБ возникают две ошибки Winsock на localhost: 10054 (на сервере) и 10053 (на клиенте). <br/><br/> Прошу прощения за некачественный код. <br/><br/> Вот функции для отправки и получения файла: <br/> // отправка файла в сокет <br/> int server::send_file_func(const std::string& file_name, SOCKET sock) <br/> { <br/> std::ifstream file(file_name, std::ios::binary); <br/> if (!file.is_open()) <br/> { <br/> // файл не открыт <br/> return -1; <br/> } <br/><br/> uint64_t file_size = std::filesystem::file_size(file_name); <br/><br/> bool errored = false; <br/> char buffer[BUFFER_SIZE]; <br/> int i = 0; <br/> int n = send(sock, reinterpret_cast(&file_size), sizeof(file_size), 0); <br/><br/> if (n < 0) <br/> { <br/> // ошибка отправки <br/> return -2; <br/> } <br/> while (i < file_size) <br/> { <br/> int size = std::min(BUFFER_SIZE, file_size - i); <br/> if (!file.read(buffer, size)) <br/> { <br/> errored = true; <br/> break; <br/> } <br/> n = send(sock, buffer, size, 0); <br/> if (n < 0) <br/> { <br/> std::cout << "server::recv_file_func() Ошибка Send(): " << WSAGetLastError() << "\n"; <br/> errored = true; <br/> break; <br/> } <br/> i += n; <br/> } <br/> file.close(); <br/> return errored ? -3 : i; <br/><br/> } <br/> // прием файла <br/> int server::recv_file_func(const std::string& file_name, SOCKET sock) <br/> { <br/> std::ofstream file(file_name, std::ios::binary); <br/> if (!file.is_open()) <br/> { <br/> // файл не открыт <br/> return -1; <br/> } <br/><br/> uint64_t file_size = 0; <br/> bool errored = false; <br/> char buffer[BUFFER_SIZE]; <br/> int i = 0; <br/> int n = recv(sock, reinterpret_cast(&file_size), sizeof(file_size), 0); <br/> <br/> if (n
  • 15 апреля 2025 г. 12:35
Ответы на вопрос 1
Ошибки Winsock 10054 и 10053 относятся к проблемам на уровне сетевого соединения. Они означают следующее:

- **10054 (WSAECONNRESET)**: Соединение было сброшено удаленным хостом. Это может произойти, если сервер закрыл соединение неожиданно или по какой-то причине.
- **10053 (WSAECONNABORTED)**: Соединение было прервано локальным хостом. Это может произойти из-за тайм-аута или потери пакетов.

Эти ошибки могут возникать по разным причинам, включая, но не ограничиваясь:

1. **Проблемы с сетью**: Убедитесь, что между клиентом и сервером нет сбоев или плохого соединения.

2. **Тайм-ауты**: Убедитесь, что сервер и клиент правильно обрабатывают долгие операции. Возможно, есть таймаут в сокетах, который необходимо увеличить.

3. **Проблемы с размером буфера или данными**: При передаче больших объемов данных, возможно, это превышает размер буфера или есть ошибка в логике передачи данных. 

4. **Неправильное закрытие соединения**: Убедитесь, что соединения закрываются корректно. Если один конец соединения закрывается, а другой продолжает попытки обмена данными, это может привести к сбросу соединения.

Теперь давайте внесем некоторые изменения в ваш код для решения этих проблем.

### Обновленный код для отправки и получения файлов

```cpp
// Отправка файла в сокет
int server::send_file_func(const std::string& file_name, SOCKET sock) {
    std::ifstream file(file_name, std::ios::binary);
    if (!file.is_open()) {
        return -1; // файл не открыт
    }

    uint64_t file_size = std::filesystem::file_size(file_name);
    char buffer[BUFFER_SIZE];
    
    // Отправка обозначения размера файла
    int n = send(sock, reinterpret_cast<char*>(&file_size), sizeof(file_size), 0);
    if (n == SOCKET_ERROR) {
        std::cout << "Ошибка отправки размера файла: " << WSAGetLastError() << "\n";
        return -2; // ошибка отправки
    }

    while (file) {
        file.read(buffer, BUFFER_SIZE);
        std::streamsize bytesRead = file.gcount();
        if (bytesRead > 0) {
            n = send(sock, buffer, bytesRead, 0);
            if (n == SOCKET_ERROR) {
                std::cout << "Ошибка Send(): " << WSAGetLastError() << "\n";
                return -3; // ошибка отправки
            }
        }
    }
    
    file.close();
    return 0; // Успех
}

// Прием файла
int server::recv_file_func(const std::string& file_name, SOCKET sock) {
    std::ofstream file(file_name, std::ios::binary);
    if (!file.is_open()) {
        return -1; // файл не открыт
    }

    uint64_t file_size = 0;
    int n = recv(sock, reinterpret_cast<char*>(&file_size), sizeof(file_size), 0);
    if (n <= 0) {
        std::cout << "Ошибка получения размера файла: " << WSAGetLastError() << "\n";
        return -2; // ошибка получения размера
    }

    char buffer[BUFFER_SIZE];
    uint64_t totalBytesRead = 0;

    while (totalBytesRead < file_size) {
        n = recv(sock, buffer, std::min(BUFFER_SIZE, static_cast<size_t>(file_size - totalBytesRead)), 0);
        if (n > 0) {
            file.write(buffer, n);
            totalBytesRead += n;
        } else if (n == 0) {
            break; // Соединение закрыто
        } else {
            std::cout << "Ошибка recv(): " << WSAGetLastError() << "\n";
            return -3; // ошибка приема
        }
    }

    file.close();
    return totalBytesRead; // Успех
}
```

### Дополнительные рекомендации:

1. **Обработка ошибок**: Убедитесь, что у вас есть адекватная обработка ошибок и возможность для повторных попыток, если соединение сбрасывается.

2. **Проверка на полный прием**: Проверяйте, что количество прочитанных байтов соответствует размеру файла.

3. **Тестирование**: Проверьте свою программу с различными сетевыми условиями, чтобы убедиться,
Похожие вопросы