使用boost :: async_write的boost :: buffer

时间:2011-11-26 16:26:18

标签: c++ buffer boost-asio asyncsocket

我目前正在使用boost :: asio,特别是使用async_write操作中的缓冲区。

当我想写一个包时,我用

async_write(sock_, boost::asio::buffer((char *)&t.getData(), sizeof(T)), boost::bind(&BoostTcpSocket::manageWrite, this, t, boost::asio::placeholders::error));

如果我当时尝试发送一个数据包,它可以正常工作。但是,如果我跟随async_write两次调用,它会向我发送两次第二个数据包。我对数据包生命周期没有任何问题。

我认为问题来自缓冲区,我想要一个packetQueue缓冲区而不是一个数据包缓冲区。

我该怎么做? 谢谢你的帮助

编辑:以下是有关代码的更多信息:

以下是它的工作原理:

int  BoostTcpSocket::manageWrite(Packet *t, const boost::system::error_code& error)
{
    if (!er)
        std::cout << "Success " << t.getData() << std::endl;
    else
        std::cout << "Error" << std::endl;
    // delete t;  => Packet LifeCycle isn't the problem here...
}

int main()
{
    boost::asio::ip::tcp::socket    sock_(io);
    sock_.connect(boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1", 8080));
    Packet *p = new Packet("data1");
    Packet *p2 = new Packet("data2");

  sock_.async_write(boost::asio::buffer((char *)&p->getData(), sizeof(Packet::data)), boost::bind(&BoostTcpSocket::manageWrite, this, p, boost::asio::placeholders::error));
  sock_.async_write(boost::asio::buffer((char *)&p2->getData(), sizeof(Packet::data)), boost::bind(&BoostTcpSocket::manageWrite, this, p2, boost::asio::placeholders::error));
io.run();
}

此代码基本上向我发送两次数据“data2”,即使服务器端std :: cout上的输出是Success data1 Success data2 ...

编辑:显然我在其他地方做错了,因为它现在正在工作..感谢大家的时间和安全;帮助!

2 个答案:

答案 0 :(得分:2)

&t.getData()处的数据必须在整个异步操作中保持不变。在收到带有成功指示的BoostUdpSocket::manageWrite回叫之前,您不得覆盖那里的数据。

答案 1 :(得分:0)

你在async_write(..)回调中绑定了两次* p。这会导致双重删除!

参见boost :: bind(...,* p,...)

sock_.async_write(boost::asio::buffer((char *)&p->getData(), sizeof(Packet::data)), boost::bind(&BoostTcpSocket::manageWrite, this, *p, boost::asio::placeholders::error)); 
sock_.async_write(boost::asio::buffer((char *)&p2->getData(), sizeof(Packet::data)), boost::bind(&BoostTcpSocket::manageWrite, this, *p, boost::asio::placeholders::error));

顺便说一句:如果您想传递* p作为参考,请考虑使用boost :: ref(..)或boost :: cref(..)。

编辑: 我认为双重删除不是你的问题,但是传递* p而没有boost :: ref(..)是问题 - 因为你要删除一个没有堆分配的对象(因为它是一个副本!)。

EDIT2: 哦,我明白了 - 在此期间,你的代码已经被破坏了。还有运行时错误吗?