Повышение ASIO и ошибок UDP

У меня есть две тестовые программы (A и B), которые почти идентичны и используют один и тот же асинхронный код boost asio UDP.

Вот прием вызова:

_mSocket.async_receive_from(
            boost::asio::buffer(_mRecvBuffer), _mReceiveEndpoint,
            boost::bind(&UdpConnection::handle_receive, this,_mReceiveEndpoint,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));
// _mReceiveEndpoint is known and good. the buffer is good too.

// вот обработчик

void handle_receive(const udp::endpoint recvFromEP, const boost::system::error_code& error,std::size_t  bytesRecv/*bytes_transferred*/)
{
    boost::shared_ptr<std::string> message(new std::string(_mRecvBuffer.c_array(),bytesRecv));
    if (!error) 
      {
      doSomeThingGood();
      } 
else {
        cerr << "UDP Recv error : " << error << endl;
    }
}

Итак, вот что происходит, все на локальном хосте.

Если я сначала запускаю программу «A», затем программа «B», «A» выдает ошибку UDP Recv: сервер: 10061. Программа «А» продолжает нормально отправлять сообщения, а программа «В» принимает их нормально.

Вы можете поменять местами «А» и «Б» в приведенном выше предложении, и это все равно верно.

ЕСЛИ я попытаюсь сбросить состояние плохого чтения, снова вызвав mSocket.async_receive_from, я получу ошибку 10054.

Я просмотрел эти ошибки в Интернете ..... не очень полезно.

У кого-нибудь есть идеи относительно того, что это значит, и как я могу восстановиться внутри программы, если это произойдет? Есть ли способ сбросить сокет?

Проверка работоспособности.... могут ли обе программы работать по петле только с двумя портами? A отправить = 20000, A получить = 20001 B отправить = 20001, B получить = 20000

TL; DR Похоже, что если я пытаюсь прослушать перед отправкой, я получаю сообщение об ошибке, и я не могу исправить это. Если я слушаю после отправки, я в порядке.

-- РЕДАКТИРОВАТЬ. Похоже, что система предотвращения вторжений McAfee делает мне что-то неприятное... Если я отлаживаю VS2010, я застреваю в их DLL.

Спасибо


person Grommit    schedule 25.03.2013    source источник
comment
По-видимому, необходимо совершить некоторые хитрости, прежде чем вы сможете совместно использовать порты между двумя процессами: stackoverflow.com/questions/4364434/   -  person Nathan Monteleone    schedule 26.03.2013


Ответы (2)


В моем обработчике получения я не вызывал _mSocket.async_receive_from() снова.... Я просто напечатал ошибку и вышел.

Глупая ошибка, просто пишу здесь, если кому-то это поможет.

Также для аналогичной проблемы с другим разрешением: _mSocket.set_option(boost::asio::socket_base::reuse_address(true));

помогает, если у вас есть несколько слушателей.

person Grommit    schedule 26.03.2013

Несколько источников объясняют, что вы должны использовать SO_REUSEADDR в окнах. Но ни в одном из них не упоминается, что можно получать сообщения UDP с привязкой к сокету и без. Приведенный ниже код привязывает сокет к локальной точке listen_endpoint, что очень важно, потому что без этого вы можете и будете получать ваши UDP-сообщения, но по умолчанию у вас будет исключительное право владения портом.

Однако, если вы установите reuse_address(true) в сокете (или на акцепторе при использовании TCP) и впоследствии привяжете сокет, это позволит нескольким приложениям или нескольким экземплярам вашего собственного приложения сделать это снова, и каждый получит все Сообщения.

// Create the socket so that multiple may be bound to the same address.
boost::asio::ip::udp::endpoint listen_endpoint(
    listen_address, multicast_port);

// == important part ==
socket_.open(listen_endpoint.protocol());
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
socket_.bind(listen_endpoint);
// == important part ==

boost::array<char, 2000> recvBuffer;
socket_.async_receive_from(boost::asio::buffer(recvBuffer), m_remote_endpoint,
        boost::bind(&SocketReader::ReceiveUDPMessage, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)

источник: http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/multicast/receiver.cpp

person Jan Wilmans    schedule 22.07.2014