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. QAbstractSocket error signal not emitted
QtWS25 Last Chance

QAbstractSocket error signal not emitted

Scheduled Pinned Locked Moved Solved General and Desktop
qabstractsocketerrordisconnectedsignal
16 Posts 4 Posters 10.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.
  • M Mark81
    3 Dec 2015, 19:18

    @koahnig
    Yeah, I see. I wonder why, though.
    Anyway, I added the following lines to my code:

    Q_DECLARE_METATYPE(QAbstractSocket::SocketError)
    qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
    

    But it returns this error:

    error: a template declaration cannot appear at block scope
    

    So I moved the Q_DECLARE_METATYPE line outside the class. Now I get:

    redefinition of 'struct QMetaTypeId<QAbstractSocket::SocketError>'
    

    I'm reading the docs about Q_DECLARE_METATYPE, I'm sorry, but I cannot understand how to use it. I don't see an example.
    Thank you

    EDIT:
    Another think I don't understand. The docs says:

    QAbstractSocket::SocketError is not a registered metatype, so for queued connections, you will have to register it with Q_DECLARE_METATYPE() and qRegisterMetaType().
    
    

    but at the end of QAbstractSocket.h I see:

    Q_DECLARE_METATYPE(QAbstractSocket::SocketState)
    Q_DECLARE_METATYPE(QAbstractSocket::SocketError)
    

    So why I have to declare them another time?

    K Offline
    K Offline
    koahnig
    wrote on 3 Dec 2015, 20:17 last edited by
    #7

    @Mark81
    I had wondered about @kshegunov 's remark. Therefore, I looked it up and found the text section to my surprise.

    However, the "and" is wrong as far as I know, you should use either one but not both.
    qRegisterMetaType and Q_DECLARE_METATYPE .

    The other things is that you have mentioned that there has been no warning in a debug window, but you should see one when the type is not registered. Therefore, try again without registration and if there is a warning.
    Since you checked already the header file and a declaration is there, this is pointing towards a bug in documentation.

    And you are right another declaration shall not be required then.

    However, coming back top your initial problem. Just to be sure. Did you check with an error condition?

    Vote the answer(s) that helped you to solve your issue(s)

    K M 2 Replies Last reply 3 Dec 2015, 20:29
    0
    • K koahnig
      3 Dec 2015, 20:17

      @Mark81
      I had wondered about @kshegunov 's remark. Therefore, I looked it up and found the text section to my surprise.

      However, the "and" is wrong as far as I know, you should use either one but not both.
      qRegisterMetaType and Q_DECLARE_METATYPE .

      The other things is that you have mentioned that there has been no warning in a debug window, but you should see one when the type is not registered. Therefore, try again without registration and if there is a warning.
      Since you checked already the header file and a declaration is there, this is pointing towards a bug in documentation.

      And you are right another declaration shall not be required then.

      However, coming back top your initial problem. Just to be sure. Did you check with an error condition?

      K Offline
      K Offline
      kshegunov
      Moderators
      wrote on 3 Dec 2015, 20:29 last edited by kshegunov 12 Mar 2015, 20:38
      #8

      @Mark81
      Actually you'll probably need only Q_DECLARE_METATYPE as this is done at compile time - exposing the type to the metatype system (I know it is an enum but it's needed for the QVariant and the like). qRegisterMetaType you'll need if creating objects by class name dynamically, and it seems for queued connections, generally you won't need to call that function, but I suggest you do.

      @koahnig
      Directly from the documentation: "Adding a Q_DECLARE_METATYPE() makes the type known to all template based functions, including QVariant. Note that if you intend to use the type in queued signal and slot connections or in QObject's property system, you also have to call qRegisterMetaType() since the names are resolved at runtime."
      Sometimes you need both.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      0
      • K koahnig
        3 Dec 2015, 20:17

        @Mark81
        I had wondered about @kshegunov 's remark. Therefore, I looked it up and found the text section to my surprise.

        However, the "and" is wrong as far as I know, you should use either one but not both.
        qRegisterMetaType and Q_DECLARE_METATYPE .

        The other things is that you have mentioned that there has been no warning in a debug window, but you should see one when the type is not registered. Therefore, try again without registration and if there is a warning.
        Since you checked already the header file and a declaration is there, this is pointing towards a bug in documentation.

        And you are right another declaration shall not be required then.

        However, coming back top your initial problem. Just to be sure. Did you check with an error condition?

        M Offline
        M Offline
        Mark81
        wrote on 4 Dec 2015, 06:41 last edited by Mark81 12 Apr 2015, 06:42
        #9

        @koahnig
        It would be interesting to know when the Q_DECLARE_METATYPE lines at the bottom of QAbstractSocket.h were added. Perhaps the docs was not updated after that, so now it should look like: "QAbstractSocket::SocketError is a declared but not a registered metatype, so for queued connections, you will have to register it with qRegisterMetaType()."
        It's weird no one else in the world has ever used this signal!

        Anyway, to test the error signal I'm simply trying to connect to my server (which works under normal conditions) with the Ethernet cable disconnected.

        I'm expecting at least one of the following errors:

        QAbstractSocket::ConnectionRefusedError	0	The connection was refused by the peer (or timed out).
        QAbstractSocket::HostNotFoundError	    2	The host address was not found.
        QAbstractSocket::SocketTimeoutError	    5	The socket operation timed out.
        QAbstractSocket::NetworkError	        7	An error occurred with the network (e.g., the network cable was accidentally plugged out).
        

        I also tried to connect before and then unplug the network cable. Nothing.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          Mark81
          wrote on 4 Dec 2015, 07:13 last edited by
          #10

          Oh dear! It works Even without qRegisterMetaType() - so the docs are definitely wrong.
          But it takes a huge time before fire, something about 30 s! This if I try to connect without the cable. After 30 seconds I get the NetworkError message.

          On the other hand, if I establish the connection and then I unplug the cable nothing happens, even after few minutes.
          Anyway I cannot wait for such a long time to inform the user the device is not connected anymore. I'm afraid I need to implement by myself a sort of software "ping" to be sure the remote device is still there. What a pity.

          1 Reply Last reply
          0
          • B Offline
            B Offline
            bsomervi
            wrote on 4 Dec 2015, 11:47 last edited by
            #11

            The default time out on QTcpSocket is 30s, you can reduce it if you want more responsive failure detection but you should be sure that you do not use a timeout less than normal round trip latency to the server.

            The docs are not wrong, you only need to register the types for Queued signal/slot connections as several have said above. Non-queued signal/slot connections are simply member function calls.

            M 1 Reply Last reply 4 Dec 2015, 19:53
            0
            • K Offline
              K Offline
              koahnig
              wrote on 4 Dec 2015, 12:33 last edited by
              #12

              To add to @bsomervi there you have the default waiting time of 30 seconds

              @bsomervi said:

              The docs are not wrong, you only need to register the types for Queued signal/slot connections as several have said above. Non-queued signal/slot connections are simply member function calls.

              This is the first time I have seen such a difference for signal-slot connections. However, certainly I know only a small fraction of the documentation.
              If you say so, I assume that you are correct about different behaviour for queued and non-queued connections.
              The documentation is at least a bit ambiguous in that respect and the sentences might require a revision for clarity.

              Vote the answer(s) that helped you to solve your issue(s)

              K 1 Reply Last reply 4 Dec 2015, 13:15
              0
              • K koahnig
                4 Dec 2015, 12:33

                To add to @bsomervi there you have the default waiting time of 30 seconds

                @bsomervi said:

                The docs are not wrong, you only need to register the types for Queued signal/slot connections as several have said above. Non-queued signal/slot connections are simply member function calls.

                This is the first time I have seen such a difference for signal-slot connections. However, certainly I know only a small fraction of the documentation.
                If you say so, I assume that you are correct about different behaviour for queued and non-queued connections.
                The documentation is at least a bit ambiguous in that respect and the sentences might require a revision for clarity.

                K Offline
                K Offline
                kshegunov
                Moderators
                wrote on 4 Dec 2015, 13:15 last edited by
                #13

                @koahnig said:

                This is the first time I have seen such a difference for signal-slot connections.

                It pops out every time you write a class that you intent to use as a signal/slot parameter in multithreaded application.

                Read and abide by the Qt Code of Conduct

                K 1 Reply Last reply 4 Dec 2015, 16:32
                0
                • K kshegunov
                  4 Dec 2015, 13:15

                  @koahnig said:

                  This is the first time I have seen such a difference for signal-slot connections.

                  It pops out every time you write a class that you intent to use as a signal/slot parameter in multithreaded application.

                  K Offline
                  K Offline
                  koahnig
                  wrote on 4 Dec 2015, 16:32 last edited by
                  #14

                  @kshegunov

                  That there is a difference between queued and non-queued is clear.
                  I had meant that there is difference in registered objects between queued and non-queued connections.
                  I came across the need to register for my own classes. So far I thought that all Qt classes are registered alreay. Thought to have read a reference somewhere, but also quite a while ago.

                  Vote the answer(s) that helped you to solve your issue(s)

                  1 Reply Last reply
                  0
                  • B bsomervi
                    4 Dec 2015, 11:47

                    The default time out on QTcpSocket is 30s, you can reduce it if you want more responsive failure detection but you should be sure that you do not use a timeout less than normal round trip latency to the server.

                    The docs are not wrong, you only need to register the types for Queued signal/slot connections as several have said above. Non-queued signal/slot connections are simply member function calls.

                    M Offline
                    M Offline
                    Mark81
                    wrote on 4 Dec 2015, 19:53 last edited by
                    #15

                    @bsomervi

                    The default time out on QTcpSocket is 30s, you can reduce it if you want more responsive failure detection
                    

                    English is not my primary language, thus I apologize if sometimes it's hard to understand what I'm reading. Anyway I read through the docs and I cannot find how to reduce this timeout. As @koahnig said I could use the waitForConnected() function but: 1. the docs say it may fail randomly on Windows, 2. it blocks the execution of my code, 3. it could work only during connection, but it isn't useful to detect a failure (i.e. the cable disconnected after).

                    I cannot find a method like: setTimeout() or similar.

                    Currently the only way I found is to periodically send back and forth a message: when I don't receive the answer in few seconds I assume the connection is lost. I hate this approach, though! I'm pretty sure the system knows if a TCP socket isn't alive anymore!

                    1 Reply Last reply
                    0
                    • B Offline
                      B Offline
                      bsomervi
                      wrote on 4 Dec 2015, 21:18 last edited by bsomervi 12 Apr 2015, 23:45
                      #16

                      @Mark81 Sorry I have misled you, I was confusing the timeout on the wait...() functions with the asynchronous signals. You do not want the wait...() functions in the GUI thread as they block.

                      The first thing to note is that normal TCP/IP will retry 12 times to send a data segment taking up to 9 minutes before it causes an error.

                      I think you have two choices in the normal TCP/IP framework.

                      If you are sending data and expecting a reply, you can start a single shot timer that is cancelled if the reply is received but causes your communications failed code to run when it times out.

                      If you are just waiting for data then you will get no notification of errors as TCP/IP will wait forever on a disconnected circuit. So in this case you must have your server send you periodic "heartbeat" data to confirm its reachability.

                      1 Reply Last reply
                      1

                      16/16

                      4 Dec 2015, 21:18

                      • Login

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