Ошибки 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. **Тестирование**: Проверьте свою программу с различными сетевыми условиями, чтобы убедиться,