Я немного схожу с ума от простого разговора TCP asio boost.
У меня есть сервер и клиент.Я использую сообщения с префиксом длины.Клиент отправляет «один», а сервер отвечает «два».Вот что я вижу:
Клиент отправляет, а сервер получает 00 00 00 03 6F 6E 65
(== 0x0003 один).
Сервер отвечает отправкой 00 00 00 03 74 77 6F
(==0x0003 два).
Теперь вот, где это очень странно (код ниже).Если клиент читает четыре байта, я ожидаю, что он получит 00 00 00 03
.Если он будет читать семь, я ожидаю увидеть 00 00 00 03 74 77 6F
.(На самом деле, он будет читать четыре (длина заголовка), а затем три (тело).)
Но то, что я на самом деле вижу, так это то, что если я читаю семь сразу, я вижу 00 00 00 03 74 77 6F
,если я прошу только четыре, я вижу 74 77 6F 03
.Это не имеет никакого смысла для меня.
Вот код, который я использую для его получения (за исключением некоторых операторов печати и т. Д.):
const int kTcpHeaderSize = 4;
const int kTcpMessageSize = 2048;
std::array<char, kTcpMessageSize + kTcpHeaderSize> receive_buffer_;
void TcpConnection::ReceiveHeader() {
boost::asio::async_read(
socket_, boost::asio::buffer(receive_buffer_, kTcpHeaderSize),
[this](boost::system::error_code error_code,
std::size_t received_length) {
if (error_code) {
LOG_WARNING << "Header read error: " << error_code;
socket_.close(); // TODO: Recover better.
return;
}
if (received_length != kTcpHeaderSize) {
LOG_ERROR << "Header length " << received_length
<< " != " << kTcpHeaderSize;
socket_.close(); // TODO: Recover better.
return;
}
uint32_t read_length_network;
memcpy(&read_length_network, receive_buffer_.data(),
kTcpHeaderSize);
uint32_t read_length = ntohl(read_length_network);
// Error: read_length is in the billions.
ReceiveBody(read_length);
});
}
Обратите внимание, что kTcpHeaderSize
4. Если я изменю его на 7 (что не имеет смысла, но только для эксперимента), я вижу поток из 7 байтов, который я ожидаю.Когда это 4, я вижу поток, который не является первыми четырьмя байтами того, что я ожидаю.
Любые указатели, что я делаю неправильно?