У меня очень странная ошибка в моем коде, но я действительно не могу понять, в чем дело. Я пытаюсь реализовать очень простой клиент, который отправляет файл на сервер через сокет;
Файл отправляется следующим образом:
- Подключение к серверу
- Отправить заголовок с информацией о файле (имя и размер файла на данный момент)
- Пока доступны чанки
- Чтение фрагмента байтов из файла
- Отправить заголовок чанк.
- Отправка данных чанка
В Boost.Asio это становится:
async_connect( // 1.
async_write( // 2.
while (file) // 3.
async_write( // 3.2
async_write( // 3.3
)
)
)
Проблема в том, что Я никогда не достигаю 3.2 (функции, которые должны отправлять заголовок чанка). Кажется, что программа застряла. Я также пытаюсь поместить бросок внутрь, чтобы увидеть, что он имеет sh.
Ниже короткого фрагмента:
namespace net = boost::asio;
namespace fs = std::filesystem;
using net::ip::tcp;
class Client {
public:
Client(net::io_context &io_context, const tcp::resolver::results_type &endpoints) {
net::async_connect(socket_, endpoints, [this](const auto &, auto) { sendMessageHeader(); });
}
private:
void sendHeader() {
// Prepare message
// ...
net::async_write(socket_, net::buffer(header_.data(), header_length()),
[this](const auto &, auto) { sendChunks(); });
}
void sendChunks() {
// ...
while(file) {
// prepare the chunk header
// ...
chunkHeaderQueue_.push();
chunkBufferQueue_.push();
// send the header
net::async_write(socket_, net::buffer(chunkHeaderQueue_.front().data(), chunkHeaderQueue_.front().size),
[this](const auto&, auto) {
auto &chunk = chunkBufferQueue_.front();
chunkHeaderQueue_.pop();
net::async_write(socket_, net::buffer(chunk), [this](const auto&, auto) {
chunkBufferQueue_.pop();
});
});
}
}
private:
boost::asio::io_context &io_context_;
tcp::socket socket_;
MessageHeader header_;
ChunkHeaderQueue chunkHeaderQueue_;
ChunkBufferQueue chunkBufferQueue_;
};
int main(int argc, char *argv[]) {
// used for async operations
net::io_context io_context;
// resolver will connect to the server
tcp::resolver resolver(io_context);
auto endpoints = resolver.resolve(argv[1], argv[2]);
// create the client and start all async operations
Client client(io_context, endpoints, {argv[3]});
// it will block until all async operation will be done!
io_context.run();
} catch (std::exception &e) {
fmt::print("Exception: {}\n", e.what());
}
return 0;
}