boost :: buffer :: async_write

问题描述:

我目前很难用boost :: asio,特别是async_write操作中的缓冲区。boost :: buffer :: 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是成功data1成功data2 ...

编辑:显然我做错了什么地方因为它现在正在工作..谢谢大家对你的时间&帮助!

+0

我认为更多的代码会有助于给你一些提示。例如。显示我们manageWrite(..) – Simon

+0

p-> getData()返回什么?为什么你需要演员?什么是数据包? – Simon

+0

p是一个包含结构的类。即时通讯尝试通过套接字发送的结构。 – Cuva

在整个异步操作中,&t.getData()处的数据必须保持不变。在收到回拨给BoostUdpSocket::manageWrite的电话之前,您不能覆盖那里的数据并显示成功信息。

+0

我不覆盖它,t分配在堆上,之后我不再触摸它。这与缓冲区大小没有任何关系?由于它的大小只是一个数据包的大小,如果我在第一个数据包未被发送时再次调用async_write,它将被覆盖? – Cuva

+0

你可以为有问题的代码显示更多的上下文吗? –

+0

这里是我的文章的更新...是不是应该工作? – Cuva

您在async_write(..)回调函数中绑定了两次* p。这导致双删除!

见的boost ::绑定(...,* 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)); 

顺便说一句:如果你wannt传递* P为基准,考虑使用boost :: REF(..)或boost :: cref(..)。

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

EDIT2: 噢,我看到了 - 您在此期间修改了代码。是否仍然存在运行时错误?

+0

对不起,我做了一个错误,当我做了例子...我改变了它。我已经检查过,我的回调函数是用p来调用的,第二次用p2来调用。但它发送相同的数据包。我在删除数据包方面没有问题,但是使用boost :: asio发送的数据... – Cuva

+0

问题不在于删除。我可以评论它。问题是网络发送两次第二个数据包,而不是第一个和第二个,或第二个和第一个...... – Cuva