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?

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.
  • BjornWB Offline
    BjornWB Offline
    BjornW
    wrote on last edited by BjornW
    #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
    • BjornWB Offline
      BjornWB Offline
      BjornW
      wrote on 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 :-)

      kshegunovK 1 Reply Last reply
      0
      • BjornWB BjornW

        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 :-)

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by
        #3

        Could you try setting it to a TCP socket?

        Read and abide by the Qt Code of Conduct

        JohanSoloJ 1 Reply Last reply
        0
        • BjornWB Offline
          BjornWB Offline
          BjornW
          wrote on last edited by
          #4

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

          kshegunovK 1 Reply Last reply
          0
          • BjornWB BjornW

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

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on 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
            • kshegunovK kshegunov

              Could you try setting it to a TCP socket?

              JohanSoloJ Offline
              JohanSoloJ Offline
              JohanSolo
              wrote on 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

              kshegunovK 1 Reply Last reply
              0
              • JohanSoloJ JohanSolo

                @kshegunov said in Multicast Issue, possible bug?:

                Could you try setting it to a TCP socket?

                For multicast you have to stick to UDP...

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on 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
                • BjornWB Offline
                  BjornWB Offline
                  BjornW
                  wrote on last edited by
                  #8

                  How to set TTL on a tcp socket, though?

                  JohanSoloJ 1 Reply Last reply
                  0
                  • BjornWB BjornW

                    How to set TTL on a tcp socket, though?

                    JohanSoloJ Offline
                    JohanSoloJ Offline
                    JohanSolo
                    wrote on last edited by JohanSolo
                    #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
                    • BjornWB Offline
                      BjornWB Offline
                      BjornW
                      wrote on 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.
                      
                      JohanSoloJ 1 Reply Last reply
                      0
                      • BjornWB BjornW

                        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.
                        
                        JohanSoloJ Offline
                        JohanSoloJ Offline
                        JohanSolo
                        wrote on 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
                        • BjornWB Offline
                          BjornWB Offline
                          BjornW
                          wrote on 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.

                          kshegunovK 1 Reply Last reply
                          0
                          • BjornWB BjornW

                            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.

                            kshegunovK Offline
                            kshegunovK Offline
                            kshegunov
                            Moderators
                            wrote on last edited by kshegunov
                            #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
                            • BjornWB Offline
                              BjornWB Offline
                              BjornW
                              wrote on 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.

                              kshegunovK 1 Reply Last reply
                              0
                              • BjornWB BjornW

                                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.

                                kshegunovK Offline
                                kshegunovK Offline
                                kshegunov
                                Moderators
                                wrote on 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

                                BjornWB 1 Reply Last reply
                                0
                                • kshegunovK kshegunov

                                  @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?

                                  BjornWB Offline
                                  BjornWB Offline
                                  BjornW
                                  wrote on 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
                                  • JohanSoloJ Offline
                                    JohanSoloJ Offline
                                    JohanSolo
                                    wrote on 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

                                    • Login

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