我用boost asio和google proto做了我的第一步。我定义了一个小测试消息
message Test
{
optional string test=1;
optional int32 value=2;
}
和一个async boost asio服务器,它使用以下函数进行响应:
void start()
{
Test test;
test.set_test("test");
test.set_value(44444);
test.PrintDebugString();
boost::asio::async_write(socket_, boost::asio::buffer(test.SerializeAsString()),
boost::bind(&tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
我的测试客户端是
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include "test.pb.h"
using boost::asio::ip::tcp;
int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::endpoint end_point(boost::asio::ip::address::from_string("127.0.0.1"), 15000);
tcp::socket socket(io_service);
socket.connect(end_point);
std::string data;
for (;;)
{
boost::array<char, 128> buf;
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buf), error);
if (error == boost::asio::error::eof)
{
Test test;
test.ParseFromString(data);
test.PrintDebugString();
break; // Connection closed cleanly by peer.
}
else if (error)
throw boost::system::system_error(error); // Some other error.
data.append(buf.begin(), buf.end());
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
如果我用我的客户端呼叫我的服务器几次,我得到不同的输出:
test: "test"
value: 44444
533 {
}
test: "test"
value: 44444
1644{
}
test: "test"
value: 44444
最后的输出是预期的,其余的是错误的。我不明白为什么我在服务器上获得更大的输出:
test: "test"
value: 44444
任何人都知道为什么我会得到像&#34; 1644 {}&#34; ?
我认为我的自我错误还是?
message Header
{
required int32 size=1;
}
新的开始
void start()
{
boost::asio::async_read(socket_,
boost::asio::buffer(m_headerData, m_sizeOfHeader),
boost::bind(&tcp_connection::handle_read_header, this,
boost::asio::placeholders::error));
}
成员:
const size_t m_sizeOfHeader = sizeof(Header::default_instance().SerializeAsString());
boost::array<char, sizeof(Header::default_instance().SerializeAsString())> m_headerData;
void handle_read_header(const boost::system::error_code& error_code)
{
if (!error_code)
{
Header header;
header.ParseFromString(std::string(m_headerData.begin(), m_headerData.end()));
header.PrintDebugString();
}
else
{
std::cout << error_code.message()<< "ERROR DELETE READ \n";
delete this;
}
我现在以这种方式尝试了我的标题,但我得到以下错误:
操作已取消或文件描述符错误
我的新客户发送:
Header header;
header.set_size(101);
boost::asio::write(socket,boost::asio::buffer(header.SerializeAsString())) ;
我认为问题是变量m_sizeOfHeader是错误的......在我的服务器端我得到8,当我在客户端打印写入的输出时我得到2 ...
我不明白为什么标题的大小不固定...我只有一个必填字段
答案 0 :(得分:0)
您忽略了读取的字节数(len
)并将垃圾追加到data
:
data.append(buf.begin(), buf.end());
尝试改为:
data.append(buf.begin(), buf.begin() + len);
此外,只有在发送单个消息并且套接字立即正常关闭(使用shutdown
)后,您的代码才能正常工作。在更复杂的场景中,您需要某种允许确定消息边界的协议。例如,您可以在消息之前的前两个字节中发送消息大小,在接收方首先读取具有预期消息大小的两个字节,然后读取消息正文。