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. Multicast Issue, possible bug?
Forum Update on Monday, May 27th 2025

Multicast Issue, possible bug?

Scheduled Pinned Locked Moved Unsolved General and Desktop
17 Posts 3 Posters 6.7k Views
  • 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.
  • B Offline
    B Offline
    BjornW
    wrote on 9 Apr 2017, 09:36 last edited by BjornW 4 Sept 2017, 09:42
    #1

    Hey guys.

    I'm having some issues with multicast. I've backtraced all the way to the examples (here and here)

    It seems that I cannot set TTL before the first write to the socket. But setting it after the first write works fine. My current setup requires TTL >= 2 for the packages to be delivered, that's how I bumped into this.

    Setup: Start receiver example on PC1, start sender example on PC2. PC1 displays 'Listening for multicast messages' and PC2 displays the sender GUI.

    Test case:

    • Perform Setup (above)

    • Change the TTL box to '2'

    • Press 'Start'

    • No data is received.

    • Change TTL box to '3' then back to '2'

    • Data is received.

    So, setting TTL seems to have no effect unless there has been a single write to the socket before. This had me pulling my hair for some time. Is this a feature or a bug? Or am I simply missing something?

    EDIT: PC1 (Receiver) uses Qt 5.7 on Windows 10 64b it. PC2 (Sender) uses Qt 5.3.2 on debian 64 bit inside a virtual machine.

    1 Reply Last reply
    0
    • B Offline
      B Offline
      BjornW
      wrote on 9 Apr 2017, 10:11 last edited by
      #2

      replacing

      udpSocket = new QUdpSocket(this);
      

      with

      udpSocket = new QUdpSocket(this);
      udpSocket->writeDatagram(QByteArray(), QHostAddress(), 0)
      

      in the sender constructor is a workaround. But it's ugly as hell :-)

      K 1 Reply Last reply 9 Apr 2017, 11:14
      0
      • B BjornW
        9 Apr 2017, 10:11

        replacing

        udpSocket = new QUdpSocket(this);
        

        with

        udpSocket = new QUdpSocket(this);
        udpSocket->writeDatagram(QByteArray(), QHostAddress(), 0)
        

        in the sender constructor is a workaround. But it's ugly as hell :-)

        K Offline
        K Offline
        kshegunov
        Moderators
        wrote on 9 Apr 2017, 11:14 last edited by
        #3

        Could you try setting it to a TCP socket?

        Read and abide by the Qt Code of Conduct

        J 1 Reply Last reply 10 Apr 2017, 20:01
        0
        • B Offline
          B Offline
          BjornW
          wrote on 9 Apr 2017, 14:23 last edited by
          #4

          I don't have time for it right now. Performing the dummy-write will have to do for now :/

          K 1 Reply Last reply 10 Apr 2017, 19:43
          0
          • B BjornW
            9 Apr 2017, 14:23

            I don't have time for it right now. Performing the dummy-write will have to do for now :/

            K Offline
            K Offline
            kshegunov
            Moderators
            wrote on 10 Apr 2017, 19:43 last edited by
            #5

            My suspicion was that the UDP socket might not be bound yet at the moment you set the TTL. When you return to the issue, do let us know how it turned out.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • K kshegunov
              9 Apr 2017, 11:14

              Could you try setting it to a TCP socket?

              J Offline
              J Offline
              JohanSolo
              wrote on 10 Apr 2017, 20:01 last edited by
              #6

              @kshegunov said in Multicast Issue, possible bug?:

              Could you try setting it to a TCP socket?

              For multicast you have to stick to UDP...

              `They did not know it was impossible, so they did it.'
              -- Mark Twain

              K 1 Reply Last reply 10 Apr 2017, 21:24
              0
              • J JohanSolo
                10 Apr 2017, 20:01

                @kshegunov said in Multicast Issue, possible bug?:

                Could you try setting it to a TCP socket?

                For multicast you have to stick to UDP...

                K Offline
                K Offline
                kshegunov
                Moderators
                wrote on 10 Apr 2017, 21:24 last edited by
                #7

                @JohanSolo said in Multicast Issue, possible bug?:

                For multicast you have to stick to UDP...

                I know that, I meant for any regular TCP socket connection.

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  BjornW
                  wrote on 11 Apr 2017, 07:18 last edited by
                  #8

                  How to set TTL on a tcp socket, though?

                  J 1 Reply Last reply 11 Apr 2017, 07:23
                  0
                  • B BjornW
                    11 Apr 2017, 07:18

                    How to set TTL on a tcp socket, though?

                    J Offline
                    J Offline
                    JohanSolo
                    wrote on 11 Apr 2017, 07:23 last edited by JohanSolo 4 Nov 2017, 07:23
                    #9

                    @BjornW said in Multicast Issue, possible bug?:

                    How to set TTL on a tcp socket, though?

                    On linux use setsockopt and setsockopt on windows. The option name is IP_MULTICAST_TTL on both platforms

                    `They did not know it was impossible, so they did it.'
                    -- Mark Twain

                    1 Reply Last reply
                    0
                    • B Offline
                      B Offline
                      BjornW
                      wrote on 11 Apr 2017, 07:28 last edited by
                      #10

                      Remember that this is the Qt forums :D. I'm dealing with QTcpSocket/QUdpSocket

                      I do set set QAbstractSocket::MulticastTtlOption (Which should correspond to IP_MULTICAST_TTL). But I don't see whats that does for a TCP socket.

                      QAbstractSocket::MulticastTtlOption - Set this to an integer value to set IP_MULTICAST_TTL (TTL for multicast datagrams) socket option.
                      
                      J 1 Reply Last reply 11 Apr 2017, 07:31
                      0
                      • B BjornW
                        11 Apr 2017, 07:28

                        Remember that this is the Qt forums :D. I'm dealing with QTcpSocket/QUdpSocket

                        I do set set QAbstractSocket::MulticastTtlOption (Which should correspond to IP_MULTICAST_TTL). But I don't see whats that does for a TCP socket.

                        QAbstractSocket::MulticastTtlOption - Set this to an integer value to set IP_MULTICAST_TTL (TTL for multicast datagrams) socket option.
                        
                        J Offline
                        J Offline
                        JohanSolo
                        wrote on 11 Apr 2017, 07:31 last edited by
                        #11

                        @BjornW said in Multicast Issue, possible bug?:

                        Remember that this is the Qt forums :D. I'm dealing with QTcpSocket/QUdpSocket

                        My bad... sorry!

                        According to wikipedia, TTL for UDP and TCP simply defines the number of subnets the packet is allowed to travel through: "The TTL field is set by the sender of the datagram, and reduced by every router on the route to its destination. If the TTL field reaches zero before the datagram arrives at its destination, then the datagram is discarded and an ICMP error datagram (11 - Time Exceeded) is sent back to the sender."

                        `They did not know it was impossible, so they did it.'
                        -- Mark Twain

                        1 Reply Last reply
                        0
                        • B Offline
                          B Offline
                          BjornW
                          wrote on 11 Apr 2017, 08:22 last edited by
                          #12

                          Yes that is correct. The issue is that the following does not work when TTL >= 2 is needed:

                          udpSocket = new QUdpSocket(this);
                          udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption, 2)
                          udpSocket->writeDatagram(someData, someAddress, somePort)
                          

                          but the following DOES work:

                          udpSocket = new QUdpSocket(this);
                          udpSocket->writeDatagram(QByteArray(), QHostAddress(), 0)
                          udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption, 2)
                          udpSocket->writeDatagram(someData, someAddress, somePort)
                          

                          Seems unintended.

                          K 1 Reply Last reply 11 Apr 2017, 08:59
                          0
                          • B BjornW
                            11 Apr 2017, 08:22

                            Yes that is correct. The issue is that the following does not work when TTL >= 2 is needed:

                            udpSocket = new QUdpSocket(this);
                            udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption, 2)
                            udpSocket->writeDatagram(someData, someAddress, somePort)
                            

                            but the following DOES work:

                            udpSocket = new QUdpSocket(this);
                            udpSocket->writeDatagram(QByteArray(), QHostAddress(), 0)
                            udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption, 2)
                            udpSocket->writeDatagram(someData, someAddress, somePort)
                            

                            Seems unintended.

                            K Offline
                            K Offline
                            kshegunov
                            Moderators
                            wrote on 11 Apr 2017, 08:59 last edited by kshegunov 4 Nov 2017, 08:59
                            #13

                            @BjornW said in Multicast Issue, possible bug?:

                            udpSocket = new QUdpSocket(this);
                            udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption, 2)
                            udpSocket->writeDatagram(someData, someAddress, somePort)
                            

                            As I noted you should try binding the socket first. I.e. call bind() after the constructor. E.g.

                            udpSocket = new QUdpSocket(this);
                            udpSocket->bind();
                            udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption, 2);
                            

                            My suspicion is that this call fails silently if you don't. Sending an empty datagram should call bind() and initialize the socket for you, but I can't see the flags applied in the deferred initialization code, namely here.

                            Read and abide by the Qt Code of Conduct

                            1 Reply Last reply
                            0
                            • B Offline
                              B Offline
                              BjornW
                              wrote on 11 Apr 2017, 09:09 last edited by
                              #14

                              I will try that when I get back home.

                              I was under the impression that bind() is used when listening to a socket, but then I'm relatively new to network programming.

                              The multicast sender example does not use bind.

                              From the docs

                              For UDP sockets, after binding, the signal QUdpSocket::readyRead() is emitted whenever a UDP datagram arrives on the specified address and port. Thus, This function is useful to write UDP servers. 
                              

                              No mention that it is required for sending or a client.

                              K 1 Reply Last reply 11 Apr 2017, 09:16
                              0
                              • B BjornW
                                11 Apr 2017, 09:09

                                I will try that when I get back home.

                                I was under the impression that bind() is used when listening to a socket, but then I'm relatively new to network programming.

                                The multicast sender example does not use bind.

                                From the docs

                                For UDP sockets, after binding, the signal QUdpSocket::readyRead() is emitted whenever a UDP datagram arrives on the specified address and port. Thus, This function is useful to write UDP servers. 
                                

                                No mention that it is required for sending or a client.

                                K Offline
                                K Offline
                                kshegunov
                                Moderators
                                wrote on 11 Apr 2017, 09:16 last edited by
                                #15

                                @BjornW said in Multicast Issue, possible bug?:

                                I was under the impression that bind() is used when listening to a socket, but then I'm relatively new to network programming.
                                The multicast sender example does not use bind.

                                No, bind is needed. In any case writeDatagram() will bind the socket for you (internally). The problem I see is that Qt's code doesn't apply the flags after the socket is initialized. I may be completely off, but I'd say it's a minor bug. On a related note, does the example code set the TTL properly, as I really don't see any significant difference from your code?

                                Read and abide by the Qt Code of Conduct

                                B 1 Reply Last reply 11 Apr 2017, 11:34
                                0
                                • K kshegunov
                                  11 Apr 2017, 09:16

                                  @BjornW said in Multicast Issue, possible bug?:

                                  I was under the impression that bind() is used when listening to a socket, but then I'm relatively new to network programming.
                                  The multicast sender example does not use bind.

                                  No, bind is needed. In any case writeDatagram() will bind the socket for you (internally). The problem I see is that Qt's code doesn't apply the flags after the socket is initialized. I may be completely off, but I'd say it's a minor bug. On a related note, does the example code set the TTL properly, as I really don't see any significant difference from your code?

                                  B Offline
                                  B Offline
                                  BjornW
                                  wrote on 11 Apr 2017, 11:34 last edited by
                                  #16

                                  @kshegunov

                                  I'll describe what happens in my original test case

                                  • Start the applications // <-- No 'bind' is called anywhere in the sender code
                                  • Change the TTL box to '2' //<-- the ttlChanged slot is invoked where udpSocket->setSocketOption(QAbstractSocket::MulticastTtlOption, 2); is called.
                                  • Press 'Start'
                                  • Data i sent but no data is received //<-- Because 1: My system setup requires TTL >= 2 for data to reach destination and 2: the previous setting of MulticastTtlOption has not been applied properly
                                  • Change TTL box to '3' then back to '2' // <-- once again, the ttlChanged slot is invoked and the setSocketOption method is called. This time, writeDatagram has been called multiple times already (implicitly calling bind()?)
                                  • Data is sent and is now also received properly
                                  1 Reply Last reply
                                  0
                                  • J Offline
                                    J Offline
                                    JohanSolo
                                    wrote on 11 Apr 2017, 11:37 last edited by
                                    #17

                                    My guess is that the socket uses implicit binding, which is a current way to proceed. But I would expect udpSocket->setSocketOption to return an error "invalid socket" or something approaching.

                                    `They did not know it was impossible, so they did it.'
                                    -- Mark Twain

                                    1 Reply Last reply
                                    0

                                    1/17

                                    9 Apr 2017, 09:36

                                    • Login

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