Search code examples
c++windowsudpboost-asiorecvfrom

Boost UDP recvfrom not getting packets from network


I am trying to get data from a device which sends data using UDP using the code below:

#include "Boost.UdpLayer.h"
#include <iostream>
#include <boost/asio.hpp>

using namespace boost::asio;

UdpLayer::UdpLayer(const std::string _ip, const int _port, Bugeye* instance)
{
    ip = _ip;
    port = _port;
    device = instance;
    Start();
}

void UdpLayer::Send(const char* message, const int length)
{
    if (!boostSocket)
        return;

    boostSocket->send_to(buffer(message, length), deviceEndpoint);
    std::cout << "Interrogated on port " << deviceEndpoint.port() << std::endl;
    std::cout << "My local port is " << GetLocalPort() << std::endl;
    std::fill(recv_buffer.begin(), recv_buffer.end(), 0);
    ip::udp::endpoint rep;

    try
    {
        volatile int sz = boostSocket->receive_from(buffer(recv_buffer), rep);
    if(sz > 0)
    {
        std::cout << "Received reply on port " << rep.port() << std::endl;
        device->ParsePacket(recv_buffer, sz);
    }
    }
    catch (std::exception& ex)
    {
    std::cout << std::endl << "Exception " << ex.what() << std::endl << std::endl;
    }
}

int UdpLayer::GetLocalPort() const
{
    return boostSocket->local_endpoint().port();
}

void UdpLayer::Start()
{
    boostSocket = std::make_shared<ip::udp::socket>(io_service);
    deviceEndpoint = ip::udp::endpoint(ip::address::from_string(ip), port);
    io_service.run();
    boostSocket->open(ip::udp::v4());
    boostSocket->connect(deviceEndpoint);
    boostSocket->set_option(boost::asio::detail::socket_option::integer<SOL_SOCKET, SO_RCVTIMEO>{ 2000 });

}

void UdpLayer::Terminate()
{
    if (boostSocket)
    {
    boostSocket->shutdown(ip::udp::socket::shutdown_both);
    boostSocket.reset();
    }

    io_service.stop();
}

I have used Wireshark to sniff packets in and out the device and the device is replying appropriately.

Wireshark packets

There's a MFC (32 bit) application which relies on CAsyncReceive which gets packets properly. I have checked packets sent by the MFC application and packets sent by the code above and both match.

I have tried porting code from Boost to Winsock2 without any success. I am unsure if any flags must be set so this packet will make it's way through device->ParsePacket. Payloads are small in size: 95 bytes so I believe a buffer overrun is not the case here.

I also tried to disable Windows Firewall entirely - no success. I wonder if there's anything else that must be done like setting an option so this will work properly.


Solution

  • I was able to fix it by creating a local separete server bound to a free port. This port is sent to the device as part of the communication packet. The device then uses this port number to reply back.