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()
    可能就是您所需要的
  • 确保您正在使用
    O\u NDELAY
    打开套接字,否则将在写入时增加200ms。通过在代码中适当的地方调用
    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);
...