boost :: buffer с boost :: async_write - PullRequest
0 голосов
/ 26 ноября 2011

У меня сейчас проблемы с 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 - это данные успеха. Данные успеха2 ...

РЕДАКТИРОВАТЬ: Очевидно, я где-то делал что-то не так, потому что теперь он работает .. Спасибо всем за ваше время и помощь!

Ответы [ 2 ]

2 голосов
/ 26 ноября 2011

Данные на &t.getData() должны оставаться неизменными на протяжении всей асинхронной операции.Вы не должны перезаписывать данные там до получения обратного вызова на BoostUdpSocket::manageWrite с указанием успеха.

0 голосов
/ 27 ноября 2011

Вы дважды связали * p в ваших обратных вызовах async_write (..). Это приводит к двойному удалению!

См. 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 (..).

EDIT: Двойное удаление, я думаю, не ваша проблема, но проблема в передаче * p без boost :: ref (..) - поскольку вы удаляете объект, который не выделен в куче (потому что это копия!).

EDIT2: О, я вижу - у вас есть исправленный код в это время. Есть ли еще ошибка во время выполнения?

...