C++ read#u一些()可以工作,但速度很慢,read()不';T
下面的代码肯定能工作,但并不像我预期的那么快 我希望我的程序能够以非常快的速度读取数据。还有一个商业应用程序连接到同一台服务器&以惊人的速度检索数据。服务器端不是问题C++ read#u一些()可以工作,但速度很慢,read()不';T,c++,boost,boost-asio,C++,Boost,Boost Asio,下面的代码肯定能工作,但并不像我预期的那么快 我希望我的程序能够以非常快的速度读取数据。还有一个商业应用程序连接到同一台服务器&以惊人的速度检索数据。服务器端不是问题 class A { //... boost::asio::ip::tcp::socket* myPort; } void A::OpenPort() { if(myPort) { if(myPort->is_open()) { ret
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();
}
}
在请求下一个数据之前,我必须处理接收到的数据,因此我不能使用async_read()。以下几点:
- 有了TCP,你永远无法确定你会一次收到所有东西
- 因为您最多只能读取一个分隔符,
可能就是您所需要的read\u until()
- 确保您正在使用
打开套接字,否则将在写入时增加200ms。通过在代码中适当的地方调用O\u NDELAY
来实现这一点myPort->set_选项(tcp::no_delay(true))
- 睡觉不是个好主意。设计您的代码,使其不必要
- 如果套接字关闭,代码似乎会进入一个无止境的循环
- 您可以调用
,而不检查返回值。您可能应该调用write_some()
,以确保所有数据都已写入write()
- 如果您有许多线程,那么将代码重新设计为异步可能会有所改进
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);
...
您可能需要考虑重新设计程序以使用异步函数。每个异步读取回调都会收到消息的一部分,当收到完整的消息时,您将其放入队列中,让主线程处理。您的代码很奇怪。若你们得到了这条河的尽头,你们将继续下去,就好像它并没有发生一样。您似乎还在测试
is\u open()
endlessy。你不应该那样做。除非连接存在,否则您的代码不应该是可访问的。您对试图解决的实际问题的描述非常模糊。你说的“速度非常好”是什么意思?你的意思是这需要太多的时间?它接收数据的速度是否不如发送数据的速度快?“我必须在请求下一个数据之前处理接收到的数据,因此我不能使用async_read()。”我不确定我是否遵循了。您可以使用async\u read
然后在完成处理程序中处理请求的更多数据。@user3924882如果您想一次读取数据,您需要使用read\u直到
或async\u read
设置在回车和换行时终止。如果您想一次性读取所有数据,则必须有一段代码确定数据的结尾,您必须编写该代码。(TCP不会将字节“粘合”在一起。如果您需要,您必须这样做。)不要担心无休止的循环。我在这里补充说,这不是我正在研究的完整解决方案。Sleep()也不是问题。我编辑了我的帖子。@user3924882好的,当然可以。其他评论站@user3924882如果您在代码中有睡眠来“改进”东西,这是潜在设计问题的一个迹象。问题不明显是read\u some()
。我怀疑重新思考一下您的代码会有所帮助。myPort->set_选项(tcp::no_delay(true)),没有什么改进。我应该应用更多的TCP套接字技巧…@user3924882现在你需要量化你的问题,而不是依靠心理调试。你的问题有多大?您的代码中还发生了什么?
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);
...