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
Forum Updated to NodeBB v4.3 + New Features

Problem binding UDP (server) socket to an interface

Scheduled Pinned Locked Moved General and Desktop
2 Posts 2 Posters 5.8k 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 14 May 2013, 21:51 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 5 Nov 2013, 18:27 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