【问题标题】:Problems using boost::asio::async_read()使用 boost::asio::async_read() 的问题
【发布时间】:2010-12-24 17:03:06
【问题描述】:

这是我使用的代码:

class Server
{
.....

void Server::accepted()
{
    std::cout << "Accepted!" << std::endl;

    boost::array<char, 1> buf;
    boost::asio::async_read(socket, boost::asio::buffer(buf),
        boost::bind(&Server::handleRead, this, buf, boost::asio::placeholders::error));
}

void Server::handleRead(boost::array<char, 1> buf, const boost::system::error_code& error)
{
    if(!error)
    {
        std::cout << "Message: " << buf.data() << std::endl;
    }
    else
    {
        std::cout << "Error occurred." << std::endl;
    }
}

.....
}

问题是我总是从客户端获得相同的数据:一个特定的字符。 在我的客户端中,我尝试发送其他字符,但服务器仍然显示相同的字符。

当我尝试读取超过 1 个字节时,我收到一个错误,指出在初始化之前使用了 buf 变量。

【问题讨论】:

    标签: c++ boost boost-asio


    【解决方案1】:

    您正在使用局部变量buf 作为读取缓冲区,这很危险并且不起作用。此外,您只是将该缓冲区的原始内容发送到处理程序。因此,您需要使用寿命更长的缓冲区。像这样的:

    class Server
    {
    .....
    
    boost::array<char, 1> buf;
    
    void Server::accepted()
    {
        std::cout << "Accepted!" << std::endl;
    
        boost::asio::async_read(socket, boost::asio::buffer(buf),
            boost::bind(&Server::handleRead, this, boost::asio::placeholders::error));
    }
    
    void Server::handleRead(const boost::system::error_code& error)
    {
        if(!error)
        {
            std::cout << "Message: " << buf.data() << std::endl;
        }
        else
        {
            std::cout << "Error occurred." << std::endl;
        }
    }
    
    .....
    }
    

    编辑:或者,使用堆分配的缓冲区(不确定代码是否正确,但您会明白的):

    void Server::accepted()
    {
        std::cout << "Accepted!" << std::endl;
    
        boost::shared_ptr<boost::array<char, 1>> buf(new boost::array<char, 1>);
    
        boost::asio::async_read(socket, boost::asio::buffer(*buf),
            boost::bind(&Server::handleRead, this, buf, boost::asio::placeholders::error));
    }
    
    void Server::handleRead(boost::shared_ptr<boost::array<char, 1>> buf, const boost::system::error_code& error)
    {
        if(!error)
        {
            std::cout << "Message: " << buf->data() << std::endl;
        }
        else
        {
            std::cout << "Error occurred." << std::endl;
        }
    }
    

    【讨论】:

    • +1 使用异步方法时,调用者有责任确保缓冲区在调用的整个生命周期内有效。
    • 谢谢它的工作,但有一个小问题。我将客户端配置为发送“aaaaaa”,将服务器配置为读取 6 个字符。服务器成功读取字符但不干净:“消息:aaaaaaÌÌÌÌÌÌ(c².^÷0”。这是我在服务器控制台中看到的输出。我还尝试将 buf.data() 写入文件,但仍然是相同的输出。
    • 那是因为字符串不是以空值结尾的。因此,您需要使用 7 个字符的缓冲区,或者让客户端发送一个以空字符结尾的字符串,或者让服务器手动将第 7 个字符设置为空。或者你可以使用 std::string 作为缓冲区,只记得在使用之前调用 .resize(6) 。
    • 所以最后一个问题与 boost::asio 无关 :) 谢谢,效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多