gpt4 book ai didi

C++ Linux Google Protobuf + boost::asio 无法解析

转载 作者:可可西里 更新时间:2023-11-01 02:33:58 24 4
gpt4 key购买 nike

我正在尝试通过 TCP 通过 boost::asio 套接字发送 Google Protobuf 消息。我认识到 TCP 是一种流式传输协议(protocol),因此我在消息通过套接字之前对其执行长度前缀。我有代码工作,但它似乎只在某些时候工作,即使我重复相同的调用而不改变环境。有时我会收到以下错误:

[libprotobuf ERROR google/protobuf/message_lite.cc:123] Can't parse message of type "xxx" because it is missing required fields: Name, ApplicationType, MessageType

原因很容易理解,但我无法挑出为什么这只是有时发生并且大多数时候解析得很好。只需让一个客户端与服务器通信并简单地重新启动进程,就很容易重现错误。

下面是套接字代码片段。

const int TCP_HEADER_SIZE = 8;

发件人:

bool Write(const google::protobuf::MessageLite& proto) {
char header[TCP_HEADER_SIZE];
int size = proto.ByteSize();
char data[TCP_HEADER_SIZE + size];
sprintf(data, "%i", size);
proto.SerializeToArray(data+TCP_HEADER_SIZE, size);
boost::asio::async_write(Socket,
boost::asio::buffer(data, TCP_HEADER_SIZE + size),
boost::bind(&TCPSender::WriteHandler,
this, _1, _2));
}

接收方:

std::array<char, TCP_HEADER_SIZE> Header;
std::array<char, 8192> Bytes;

void ReadHandler(const boost::system::error_code &ec,
std::size_t bytes_transferred) {
if(!ec) {
int msgsize = atoi(Header.data());
if(msgsize > 0) {
boost::asio::read(Socket, boost::asio::buffer(Bytes,static_cast<std::size_t>(msgsize)));
ReadFunc(Bytes.data(), msgsize);
}
boost::asio::async_read(Socket, boost::asio::buffer(Header, TCP_HEADER_SIZE),
boost::bind(&TCPReceiver::ReadHandler, this, _1, _2));
}
else {
std::cerr << "Server::ReadHandler::" << ec.message() << '\n';
}
}

读取函数:

void HandleIncomingData(const char *data, const std::size_t size) {
xxx::messaging::CMSMessage proto;
proto.ParseFromArray(data, static_cast<int>(size));
}

我应该提一下,我需要它尽可能快,因此我们也非常感谢任何优化。

最佳答案

程序调用未定义的行为,因为它无法满足 boost::asio::async_write() 的生命周期要求的 buffers 参数:

[...] ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.

Write() 函数中,boost::asio::async_write() 将立即返回,并可能导致 data 丢失在异步写入操作完成之前超出范围。要解决此问题,请考虑延长底层缓冲区的生命周期,例如通过将缓冲区与操作相关联并在处理程序中执行清理,或者使缓冲区成为 TCPSender 上的数据成员。

关于C++ Linux Google Protobuf + boost::asio 无法解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31597861/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com