下面的代码绝对有效,但并不像我预期的那样快。
我希望我的程序以非常好的速度读取数据。还有另一个商业应用程序连接到同一服务器和以惊人的速度检索数据。服务器端不是问题。
class A
{
//...
boost::asio::ip::tcp::socket* myPort;
}
void A::OpenPort()
{
if(myPort)
{
if(myPort->is_open())
{
return;
}
}
// make the connection
Connect();
if(! myPort->is_open())
{
return;
}
// set the protocol
static string init("INIT\r\n");
myPort->write_some(boost::asio::buffer(init.c_str(), init.length()));
}
void A::Read()
{
static string prev_msg = "";
try
{
OpenPort();
while(true)
{
boost::system::error_code error;
boost::asio::streambuf streamBuf;
boost::asio::streambuf::mutable_buffers_type mutableBuffer = streamBuf.prepare(614400);
size_t bytes_transferred = myPort->read_some(boost::asio::buffer(mutableBuffer), error);
if (error)
{
if (error != boost::asio::error::eof)
{
throw boost::system::system_error(error); // Some other error.
}
}
// add to any previous message we might not have processed
streamBuf.commit(bytes_transferred);
istreambuf_iterator<char> sbit(&streamBuf);
istreambuf_iterator<char> end;
string s(sbit, end);
prev_msg.append(s);
string delimiter1 = ",\r\n";
size_t pos1 = 0;
string response;
while ((pos1 = prev_msg.find(delimiter1)) != std::string::npos)
{
response = prev_msg.substr(0, pos1);
//SOME PROCESSING ON THE RESPONSE RECEIVED
}
}
}
catch (boost::system::system_error const& ex)
{
cout<<ex.what();
}
}
显然,问题是read_some(),程序在一次读操作中不读取完整数据,有时它接收614000字节,有时甚至更少。
我不想强制对缓冲区大小施加任何限制,无论服务器发送什么,程序都应该一次性读取所有数据。
因此,我决定只使用read()。但是,现在程序停留在read(); read()调用不会返回。
boost::asio::streambuf streamBuf;
size_t bytes_transferred = read(*myPort, streamBuf, error);
if (error)
{
if (error != boost::asio::error::eof)
{
throw boost::system::system_error(error); // Some other error.
}
}
我必须在请求下一个数据之前处理收到的数据,因此我不能使用async_read()。
答案 0 :(得分:1)
一些事情:
read_until()
可能就是您所追求的目标。O_NDELAY
打开套接字,否则将为写入添加200毫秒。通过在代码中的适当位置调用myPort->set_option(tcp::no_delay(true))
来执行此操作。write_some()
。您应该致电write()
以确保所有数据都已写入。答案 1 :(得分:1)
不要在每个循环上分配新缓冲区,只在循环外执行一次。
while(true)
{
boost::system::error_code error;
boost::asio::streambuf streamBuf;
boost::asio::streambuf::mutable_buffers_type mutableBuffer = streamBuf.prepare(614400);
size_t bytes_transferred = myPort->read_some(boost::asio::buffer(mutableBuffer), error);
...
替换为
boost::system::error_code error;
boost::asio::streambuf streamBuf;
boost::asio::streambuf::mutable_buffers_type mutableBuffer = streamBuf.prepare(614400);
while(true)
{
size_t bytes_transferred = myPort->read_some(boost::asio::buffer(mutableBuffer), error);
...