由于使用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次send函数(我想我的数据缝被发送了),但是myclient缝却从不获取数据...
答案 0 :(得分:0)
您的客户挂在这条线上
boost::asio::read(socket, response);
因为上面与
相同boost::asio::read(socket, response, boost::asio::tranfer_all());
the documentation中描述的内容。
您使用带有完成条件的read
重载。这些函子有三种:transfer_all_t
,transfer_exactly_t
和transfer_at_least_t
。它们每个都有operator()()
,如果读取操作完成,则返回0-see reference。
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
和transfer_all
结束,则可以 create 来查看读取的数据。您可以在服务器端关闭套接字(用于发送操作),也可以仅关闭此套接字。然后,您可以更改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));