通过 Socket 通过 boost asio 发送和接收 protobuf 数据
Sending and receiving protobuf data over Socket via boost asio
我想通过TCP套接字将Protobuf数据从我的服务器发送到我的客户端。
我测试了我的客户端和服务器,TCP连接工作正常。
所以我尝试序列化我的数据并使用 streambuf 发送它。
在我的服务器中:
void SendData(protobufType data){
std::ostream ostream(&this->m_streambuf);
data.SerializeToOstream(&ostream);
std::cout<<"Send data"<< std::endl;
boost::asio::write(this->m_socket, this->m_streambuf);
}
在我的客户端中:
boost::asio::streambuf response;
boost::asio::read(socket, response);
std::cout<<"Data received"<< std::endl;
我运行了 3 倍的发送函数(我猜我的数据接缝要发送),但我的客户端接缝永远不会获取数据......
你的客户端挂在这条线上
boost::asio::read(socket, response);
因为上面和
boost::asio::read(socket, response, boost::asio::tranfer_all());
文档中描述的内容。
您使用read
重载,它采用完成条件。这些函子有三种:transfer_all_t
、transfer_exactly_t
和transfer_at_least_t
。它们中的每一个都有operator()()
如果读取操作完成,则返回 0 - 请参阅参考。
transfer_all_t::opeator()()
的代码是:
template <typename Error>
std::size_t operator()(const Error& err, std::size_t)
{
return !!err ? 0 : default_max_transfer_size;
}
因此,仅当发生错误时才返回 0。
transfer_at_least_t::operator()()
是:
template <typename Error>
std::size_t operator()(const Error& err, std::size_t bytes_transferred)
{
return (!!err || bytes_transferred >= minimum_)
? 0 : default_max_transfer_size;
}
如您所见,如果发生错误或至少传输了minimum_
个字节,则返回 0。
如果您知道read
withtransfer_all
在发生错误时结束,则可以创建此错误以查看读取的数据。您可以在服务器端关闭套接字(用于发送操作)或仅关闭此套接字。然后,您可以更改read
调用以获取error_code
,您应该看到文件结尾为错误:
boost::system::error_code ec;
boost::asio::read(socket,response,ec);
if (ec)
{
cout << ec.message() << endl; // End of file
// if ec is End of file you can see what data was read into streambuf
}
您发送一个序列化对象,因此您知道该对象的大小,为什么不使用发送对象大小的方法(例如在 4 个字节上),然后在此标头之后稍后发送对象的内容。
在客户端:
array<char,4> length;
boost::asio::read(socket,boost::asio::buffer(length));
int contentLen = /*conversion from length array into integer */
vector<char> content( contentLen );
boost::asio::read(socket,boost::asio::buffer(content));
相关文章:
- 通过方法访问结构
- 通过递归进行因子分解
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 尝试通过多个向量访问变量时,向量下标超出范围
- C++如何通过用户输入删除列表元素
- 通过多个头文件使用常量变量
- 是否可以通过C++扩展强制多个python进程共享同一内存
- C++:如何通过 curl 调用使用 HTTP post 请求发送二进制数据(protobuf 数据)
- 通过 Socket 通过 boost asio 发送和接收 protobuf 数据
- 如何通过fifo使用protobuf的SerializeToOstream和ParseFromIstream进行IPC?
- C++ protobuf:如何通过"SerializeToOstream()"将多条消息写入文件
- 通过Google Protobuf发送二进制文件数据
- 有没有人试图通过 JNI 将 protobuf 对象从 C++ 返回到 Java
- 如何在c++中使用protobuf通过套接字发送序列化数据
- 如何通过 REST SDK 接收二进制数据 (protobuf)
- 由于PROTOBUF服务器中的字符串数据类型变量和客户端通过cpp中recv端的套接字进行通信,因此正在获取segfau
- 通过winpcap API读取protobuf消息
- 在Java中反序列化从c++通过JNI传递的protobuf ByteArray
- 无法通过 UDP protobuf 将大于 127 的整数值从 c++ 发送到 java
- c++中通过套接字发送protobuf的串行化