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. QUdpSocket: Can't make multicast work on loopback interface (localhost)
Forum Updated to NodeBB v4.3 + New Features

QUdpSocket: Can't make multicast work on loopback interface (localhost)

Scheduled Pinned Locked Moved General and Desktop
2 Posts 1 Posters 3.9k 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.
  • A Offline
    A Offline
    artem_pisarenko
    wrote on 23 Oct 2013, 04:30 last edited by
    #1

    Please, help setup sockets to receive and send multicast datagrams in following scenario: user selects network interface (because it may have multiple networks on its computer, or even have no networks at all, in which case it must be able to select loopback interface and work locally with multiple application instances), application instance must not receive its own loopbacked packets (or it must be able to filter them out).

    Seems to be very easy, but I've spent a lot of time and broken my mind trying to make it work. I've already researched low-level sockets api, its options, examined a lot of similar issues on the web, tried all possible combinations, but no success !

    Here is result of my research, which SEEMS to work, but I don't beleive it will work on any other combination of platform and network configuration, other than my computer have:
    @
    void initNetwork() {
    //...
    /* It will be needed to filter out own loopbacked datagrams /
    local_addresses = QNetworkInterface::allAddresses();
    /
    Interface, selected by user /
    QNetworkInterface multicast_netif = <user selected>;
    Q_ASSERT(multicast_netif.isValid());
    /
    Yes, I already accept the fact, that I need two separate sockets (there are more chances to make it work than when using bidirectional one) /
    udpSocketIn = new QUdpSocket(this);
    udpSocketOut = new QUdpSocket(this);
    /
    It's important to bind to Any. No other combinations work (including LocalHost (in case if user selected loopback interface), MULTICAST_ADDR) /
    result = udpSocketIn->bind(QHostAddress::Any, MULTICAST_PORT, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
    Q_ASSERT(result);
    /
    It required to only make application know real(!) udpSocketOut->localPort() in order to be able filter own datagrams /
    result = udpSocketOut->bind();
    Q_ASSERT(result);
    /
    One of rare things, I'm sure it's correct and must be done /
    result = udpSocketIn->joinMulticastGroup(QHostAddress(MULTICAST_ADDR), multicast_netif);
    Q_ASSERT(result);
    /
    It doesn't matter, but it will fail if socket not binded /
    //result = udpSocketOut->joinMulticastGroup(QHostAddress(MULTICAST_ADDR), multicast_netif);
    //Q_ASSERT(result);
    /
    No, you can't ! If socket binded previously and loopback interface selected, datagrams will not be transfered. I don't know why. And this is major thing, which makes me think, that this configuration isn't reliable, because stupid windows will select default interface for outgoing datagrams ! /
    //udpSocketOut->setMulticastInterface(multicast_netif);
    /
    It doesn't matter, because it set by default. If set to 0, datagrams will not be transferred on loopback interface. I don't know why ! */
    //udpSocketIn->setSocketOption(QAbstractSocket::MulticastLoopbackOption, QVariant(1));
    //udpSocketOut->setSocketOption(QAbstractSocket::MulticastLoopbackOption, QVariant(1));
    //...
    }

    void sendDatagram() {
    //...
    /* It almost always return ok, regardless of datagram being sent actually or not.
    One exception is when I turn off real network interface to which it was binded by udpSocketOut->bind() call (it selected by OS, although user selected loopback interface !)
    */
    result = udpSocketOut->writeDatagram(datagram, QHostAddress((MULTICAST_ADDR), MULTICAST_PORT);
    Q_ASSERT(result == datagram.size());
    //...
    }

    void readPendingDatagrams() {
    //...
    udpSocketIn->readDatagram(datagram, &senderHost, &senderPort);
    /* Thanks to udpSocketOut->bind() we are able to filter out own packets sent from udpSocketOut */
    if ((local_addresses.contains(senderHost)) && (senderPort == udpSocketOut->localPort())) {
    // Ignore loopbacked datagram
    return;
    }
    //...
    }
    @

    I've tried use single socket, and it also SEEMS to work, but in this case I'm not be able to filter out own datagrams, because port numbers are same everywhere.

    Qt: 4.8.4
    OS: Windows 7 x64

    1 Reply Last reply
    0
    • A Offline
      A Offline
      artem_pisarenko
      wrote on 26 Oct 2013, 10:01 last edited by
      #2

      http://stackoverflow.com/a/19582161/1833765

      1 Reply Last reply
      0

      1/2

      23 Oct 2013, 04:30

      • Login

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