使用boost::asio::async_read()时出现问题

5
这是我使用的代码:
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变量在初始化之前被使用。
1个回答

13

您正在使用本地变量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;
    }
}

2
当使用异步方法时,调用者有责任确保缓冲区在调用的整个生命周期内有效。 - Sam Miller
谢谢,它有效了,但有个小问题。我配置了客户端发送“aaaaaa”,服务器读取6个字符。服务器成功地读取了这些字符,但不是干净的:"Message: aaaaaaÌÌÌÌÌÌ(c².ˆ÷0"。 这是我在服务器控制台上看到的输出。我还尝试将buf.data()写入文件,但仍然是相同的输出。 - Zippo
2
那是因为字符串没有以空字符结尾。所以你需要使用一个7个字符的缓冲区,要么让客户端发送一个以空字符结尾的字符串,要么让服务器手动将第7个字符设置为空字符。或者你可以使用std::string作为缓冲区,只需记得在使用之前调用.resize(6)即可。 - Timo
所以最后的问题与boost :: asio无关:) 谢谢,它运行得很好。 - Zippo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接