Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Problem binding UDP (server) socket to an interface
Qt 6.11 is out! See what's new in the release blog

Problem binding UDP (server) socket to an interface

Scheduled Pinned Locked Moved General and Desktop
2 Posts 2 Posters 6.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    doug65536
    wrote on last edited by
    #1

    I am writing a UDP server application that needs to know which interface received a request, so I can know what IP address to deliver in the response.

    To accomplish that, I am creating a separate UDP socket for each interface, and binding each socket to a specific interface address.

    Here is a piece of code so you can see what I am doing to initialize it:

    @PXEResponder::PXEResponder(QObject *parent)
    : QObject(parent)
    {
    bool ok;

    // Get network interface list
    addresses = QNetworkInterface::allAddresses();
    
    signalMapper = new QSignalMapper(this);
    listeners.reserve(interfaces.size());
    
    for (int i = 0; i < addresses.size(); ++i)
    {
        // Only support IPv4
        if (addresses[i].protocol() != QUdpSocket::IPv4Protocol)
            continue;
    
        qDebug() << addresses[i];
    
        // Create a UDP socket and bind it to port 67
        QUdpSocket *listener = new QUdpSocket(this);
        if (!listener->bind(addresses[i], 67, QUdpSocket::DefaultForPlatform))
        //if (!listener->bind(67))
            qDebug() << "Failed to bind DHCP listener";
    
        // Connect the readyRead signal to our slot
        ok = connect(listener, SIGNAL(readyRead()), signalMapper, SLOT(map()));
        signalMapper->setMapping(listener, i);
    
        listenerAddress.insert(listener, addresses[i]);
        listeners.push_back(listener);
    }
    
    ok = connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(on_packet(int)));
    

    }
    @

    Everything completes without error, but I don't get any readyRead signals.

    NOTE:

    • My program is running as root, so it is allowed to bind port 67
    • There is no DHCP server running on my machine
    • I am using the signal mapper so I can identify which QUdpSocket causes the event. That part works.
    • The "bind" call that doesn't work (the one that specifies an address) returns true.
    • Removing the "QUdpSocket::DefaultForPlatform" parameter doesn't help.
    • The qDebug() output (the interface address) looks correct.
    • If I comment-out the bind call that I'm trying to use, and uncomment the one that doesn't specify an interface address, everything works.

    Here's the weird part: when I bind to specific interfaces, I see the socket in the "netstat -a" output. Is there a reason I am not receiving broadcasts when bound to a specific interface?

    I found a partial answer:

    Linux won't receive broadcast packets when the socket is bound because it will only receive packets sent (directly) to the bound address. The solution is to use SO_BINDTODEVICE socket option and use INADDR_ANY as the bind address.

    Is there a way to bind to a network interface in Qt (without binding to the address of the interface)?

    1 Reply Last reply
    0
    • B Offline
      B Offline
      bagpiper
      wrote on last edited by
      #2

      try this:

      @
      #include <sys/socket.h>

      m_udpSocket = new QUdpSocket( this );
      if( m_udpSocket )
      {
      connect( m_udpSocket, SIGNAL( readyRead() ), this, SLOT( SLOT_ondataReceived() ) );
      connect( m_udpSocket, SIGNAL( disconnected() ), this, SLOT( SLOT_disconnected() ) );

       retVal = m_udpSocket->bind( QHostAddress::Any, m_port );
      

      // set the socket option here.....
      const char dev[] = "eth0";
      if (0 != setsockopt(m_udpSocket->socketDescriptor(), SOL_SOCKET, SO_BINDTODEVICE, dev, sizeof(dev) ))
      {

       }
      

      }@

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved