Я пишу программу на C ++.Мне нужно получить файл, и я использую функцию recv () через сокет TCP для этого.
download_file() {
while (left_bytes != 0 && !connection_closed) {
if (left_bytes >= buffer_max_size)
bytes_to_download = buffer_max_size;
else
bytes_to_download = left_bytes;
if (request.conn->read_data(buffer, bytes_to_download))
{
left_bytes -= buffer->get_size();
temporary_file.write_data(buffer);
} else connection_closed = true;
}
}
read_data() {
while (bytes_received < size && alive_) {
bytes_read = recv(sock_, read_buffer, size, 0);
if (bytes_read == SOCKET_ERROR) {
delete[] local_buffer;
throw SocketException(WSAGetLastError());
}
// the connection is closed
if (bytes_read == 0) alive_ = false;
else {
bytes_received += bytes_read;
buffer->add(local_buffer, bytes_read);
}
}
}
Проблема в том, что recv никогда не возвращается.Он получает весь файл, за исключением нескольких килобайт, и останавливается в recv ().Размер буфера составляет 1460. Я получаю файл, только если что-то печатаю на консоль cout каждый раз, когда вызывается recv.Только в этом случае я получаю весь файл.
В противном случае, если я установлю в качестве опции сокета WAITALL и клиент закроет соединение после отправки файла, я получу весь файл.Вот код для клиентской стороны, которая отправляет файл:
TransmitFile(file_request->connection_->get_handle_socket(), file_handler.get_file_handle(), file_request->file_size_, 65535, nullptr, nullptr, TF_USE_SYSTEM_THREAD)
РЕДАКТИРОВАТЬ
Вот как я могу отправить и прочитать размер файла между клиентом и сервером.
std::stringstream stream_;
stream_.str(std::string());
// append the file size
const __int64 file_size = htonll(GetFileSize(file_handle_, nullptr););
stream_ << ' ' << file_size << ' ';
Затем я посылаю эту строку с помощью отправки
Вот как я читаю размер файла
// Within stream_ there is all the content of the received packet
std::string message;
std::getline(stream_, message, ' ');
this->request_body_.file_size_ = ntohll(strtoll(message.c_str(), nullptr, 0));
РЕДАКТИРОВАТЬ
Я очистил код и обнаружил, что read_data () явно вызывается один раз, и я неправильно обновлял буферную переменную.Поэтому я неверно отслеживал размер содержимого в буфере, что заставило меня снова вызвать recv ().