我目前正在使用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 ...
编辑:显然我在其他地方做错了,因为它现在正在工作..感谢大家的时间和安全;帮助!答案 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: 哦,我明白了 - 在此期间,你的代码已经被破坏了。还有运行时错误吗?