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. Qt Socket error handling - How to tell the source of error and operation it occurred in
Forum Updated to NodeBB v4.3 + New Features

Qt Socket error handling - How to tell the source of error and operation it occurred in

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 4 Posters 1.5k 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.
  • F Offline
    F Offline
    Fleshbits
    wrote on last edited by
    #1

    I am learning how to use QtWebSocket. I don't see any mention whatsoever of how to handle errors in the documentation beyond:

    QAbstractSocket::SocketError QAbstractSocket::error() const
    Returns the type of error that last occurred.
    
    See also state() and errorString().
    

    and

    void QWebSocket::error(QAbstractSocket::SocketError error)
    This signal is emitted after an error occurred. The error parameter describes the type of 
    error that occurred.
    
    QAbstractSocket::SocketError is not a registered metatype, so for queued connections, you 
    will have to register it with Q_DECLARE_METATYPE() and qRegisterMetaType().
    
    Note: Signal error is overloaded in this class. To connect to this signal by using the 
    function pointer syntax, Qt provides a convenient helper for obtaining the function pointer 
    as shown in this example:
    
    connect(webSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error),
    [=](QAbstractSocket::SocketError error){ /* ... */ });
    See also error() and errorString().
    

    Of course, there is no use of either one in the example code.

    I imagine some errors are going to be common and even expected in a communication layer, such as:

    • list itemTrying to connect to a server that isn't listening
    • Trying to send when the other side hung up
    • Losing network in the middle of a read
    • Losing network in the middle of a send
    • Trying to disconnect a socket that's already disconnected etc

    So, how am I supposed to

    • Know which websocket caused the error?
    • Know what operation it was trying to perform?
    • Control program flow when the error occurs?
    Christian EhrlicherC 1 Reply Last reply
    1
    • F Fleshbits

      I am learning how to use QtWebSocket. I don't see any mention whatsoever of how to handle errors in the documentation beyond:

      QAbstractSocket::SocketError QAbstractSocket::error() const
      Returns the type of error that last occurred.
      
      See also state() and errorString().
      

      and

      void QWebSocket::error(QAbstractSocket::SocketError error)
      This signal is emitted after an error occurred. The error parameter describes the type of 
      error that occurred.
      
      QAbstractSocket::SocketError is not a registered metatype, so for queued connections, you 
      will have to register it with Q_DECLARE_METATYPE() and qRegisterMetaType().
      
      Note: Signal error is overloaded in this class. To connect to this signal by using the 
      function pointer syntax, Qt provides a convenient helper for obtaining the function pointer 
      as shown in this example:
      
      connect(webSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error),
      [=](QAbstractSocket::SocketError error){ /* ... */ });
      See also error() and errorString().
      

      Of course, there is no use of either one in the example code.

      I imagine some errors are going to be common and even expected in a communication layer, such as:

      • list itemTrying to connect to a server that isn't listening
      • Trying to send when the other side hung up
      • Losing network in the middle of a read
      • Losing network in the middle of a send
      • Trying to disconnect a socket that's already disconnected etc

      So, how am I supposed to

      • Know which websocket caused the error?
      • Know what operation it was trying to perform?
      • Control program flow when the error occurs?
      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Fleshbits said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

      Know which websocket caused the error?

      Since the signal is coming from the affected socket you know them

      Know what operation it was trying to perform?

      See first

      Control program flow when the error occurs?

      That's up to you

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      F 1 Reply Last reply
      2
      • Christian EhrlicherC Christian Ehrlicher

        @Fleshbits said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

        Know which websocket caused the error?

        Since the signal is coming from the affected socket you know them

        Know what operation it was trying to perform?

        See first

        Control program flow when the error occurs?

        That's up to you

        F Offline
        F Offline
        Fleshbits
        wrote on last edited by
        #3

        @Christian-Ehrlicher said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

        @Fleshbits said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

        Know which websocket caused the error?

        Since the signal is coming from the affected socket you know them

        Know what operation it was trying to perform?

        See first

        Control program flow when the error occurs?

        That's up to you

        No it really isn't, because what ever operation caused the error to occur has already completed (with failure), so whatever was being sent is lost, whatever was being connected to is gone, I can't throw exceptions at all either way, and I have no idea what operation was occurring. Did the connection drop in the middle of a send? I dunno. In the middle of receive? Who knows. Did the message get through? Part of it? How many bytes? Your guess is as good as mine.

        Hence the question.

        JonBJ 1 Reply Last reply
        0
        • F Fleshbits

          @Christian-Ehrlicher said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

          @Fleshbits said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

          Know which websocket caused the error?

          Since the signal is coming from the affected socket you know them

          Know what operation it was trying to perform?

          See first

          Control program flow when the error occurs?

          That's up to you

          No it really isn't, because what ever operation caused the error to occur has already completed (with failure), so whatever was being sent is lost, whatever was being connected to is gone, I can't throw exceptions at all either way, and I have no idea what operation was occurring. Did the connection drop in the middle of a send? I dunno. In the middle of receive? Who knows. Did the message get through? Part of it? How many bytes? Your guess is as good as mine.

          Hence the question.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @Fleshbits
          Well you won't necessarily know half of these answers in any case, e.g. how many bytes did or not get sent/received where. You will have note what the last operation you performed was if you need to know when, say, QWebSocket::error() occurs.

          F 1 Reply Last reply
          1
          • JonBJ JonB

            @Fleshbits
            Well you won't necessarily know half of these answers in any case, e.g. how many bytes did or not get sent/received where. You will have note what the last operation you performed was if you need to know when, say, QWebSocket::error() occurs.

            F Offline
            F Offline
            Fleshbits
            wrote on last edited by
            #5

            @JonB said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

            @Fleshbits
            Well you won't necessarily know half of these answers in any case, e.g. how many bytes did or not get sent/received where. You will have note what the last operation you performed was if you need to know when, say, QWebSocket::error() occurs.

            Very confusing.

            With a Berkeley tcp socket I would loop in a send, and it will tell me how many bytes were sent, and I'd keep sending until all my bytes went out. If an error occurred at byte 54, I've literally got a count and it returned an error code, so I know I am sending, I know only 54 bytes made it, and I can reconnect and then send the rest or the whole message again.

            Here, the operations are asynchronous operations that are exited before I am alerted of an error, so I have no information at all. All I know is "NetworkError"

            I dunno how you would keep track of what operation you are performing, because you could be in the middle of sending, when a receive occurred. It's async. You also have no control over when a receive happens and wouldn't be called back until it was complete. So, it's not like I can make some kind of states RECEIVING RECEIVED SENDING SENT CONNECTING CONNECTED DISCONNECTED and have them reflect reality, AFAIK.

            JonBJ 1 Reply Last reply
            0
            • F Fleshbits

              @JonB said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

              @Fleshbits
              Well you won't necessarily know half of these answers in any case, e.g. how many bytes did or not get sent/received where. You will have note what the last operation you performed was if you need to know when, say, QWebSocket::error() occurs.

              Very confusing.

              With a Berkeley tcp socket I would loop in a send, and it will tell me how many bytes were sent, and I'd keep sending until all my bytes went out. If an error occurred at byte 54, I've literally got a count and it returned an error code, so I know I am sending, I know only 54 bytes made it, and I can reconnect and then send the rest or the whole message again.

              Here, the operations are asynchronous operations that are exited before I am alerted of an error, so I have no information at all. All I know is "NetworkError"

              I dunno how you would keep track of what operation you are performing, because you could be in the middle of sending, when a receive occurred. It's async. You also have no control over when a receive happens and wouldn't be called back until it was complete. So, it's not like I can make some kind of states RECEIVING RECEIVED SENDING SENT CONNECTING CONNECTED DISCONNECTED and have them reflect reality, AFAIK.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @Fleshbits said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

              With a Berkeley tcp socket I would loop in a send,

              And unless you do your own threading your application would block here, which isn't great in GUI application.

              I know only 54 bytes made it,

              I could easily be wrong here and you may well know more than I, but I thought it only tells you how many bytes made it out of your program and into the OS buffer, not how many were actually sent?

              If you don't like asynchronous operation why don't you make Qt's calls synchronous like you like them to be? Then you will be much closer to the errors occurring while you are performing the operation?

              F 1 Reply Last reply
              2
              • JonBJ JonB

                @Fleshbits said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

                With a Berkeley tcp socket I would loop in a send,

                And unless you do your own threading your application would block here, which isn't great in GUI application.

                I know only 54 bytes made it,

                I could easily be wrong here and you may well know more than I, but I thought it only tells you how many bytes made it out of your program and into the OS buffer, not how many were actually sent?

                If you don't like asynchronous operation why don't you make Qt's calls synchronous like you like them to be? Then you will be much closer to the errors occurring while you are performing the operation?

                F Offline
                F Offline
                Fleshbits
                wrote on last edited by Fleshbits
                #7

                @JonB said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

                @Fleshbits said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

                With a Berkeley tcp socket I would loop in a send,

                And unless you do your own threading your application would block here, which isn't great in GUI application.

                I know only 54 bytes made it,

                I could easily be wrong here and you may well know more than I, but I thought it only tells you how many bytes made it out of your program and into the OS buffer, not how many were actually sent?

                If you don't like asynchronous operation why don't you make Qt's calls synchronous like you like them to be? Then you will be much closer to the errors occurring while you are performing the operation?

                This has nothing to do with blocking vs async, really. Although I follow that you are saying error handling would be simpler. I am not going to implement blocking sockets in a high performance communication layer though.

                Consider boost::asio::tcp

                During an asynchronous send, if an error occured, I would receive a callback with

                • which socket the error occured on
                • how many bytes were sent (to buffers)
                • the error code

                A typical callback setup looks like:

                boost::bind(&Server::handleSend, shared_from_this(),
                                            toSend.at(i),
                                            boost::asio::placeholders::error,
                                            boost::asio::placeholders::bytes_transferred));
                

                I mean, I am getting that you are telling me that information simply isn't available to me. So OK, let's accept that. What are you guys doing in your application when an error occurs such as network connection lost?

                I imagine I'd have to flag each message "sent" when called back without an error callback occurring and retain it until then? The expected callback won't occur at all if the error callback happens, right?

                For receives, I just won't even know I got anything because I won't be called back until the whole thing arrives, right? I'll just get a network connection lost error and reconnect. The other end will have to handle connection lost.

                For connect, I suppose I just don't allow sends until the connection callback is called back, in effect making my async call sync.

                Does that sound like a solid strategy?

                jsulmJ 1 Reply Last reply
                1
                • F Fleshbits

                  @JonB said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

                  @Fleshbits said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

                  With a Berkeley tcp socket I would loop in a send,

                  And unless you do your own threading your application would block here, which isn't great in GUI application.

                  I know only 54 bytes made it,

                  I could easily be wrong here and you may well know more than I, but I thought it only tells you how many bytes made it out of your program and into the OS buffer, not how many were actually sent?

                  If you don't like asynchronous operation why don't you make Qt's calls synchronous like you like them to be? Then you will be much closer to the errors occurring while you are performing the operation?

                  This has nothing to do with blocking vs async, really. Although I follow that you are saying error handling would be simpler. I am not going to implement blocking sockets in a high performance communication layer though.

                  Consider boost::asio::tcp

                  During an asynchronous send, if an error occured, I would receive a callback with

                  • which socket the error occured on
                  • how many bytes were sent (to buffers)
                  • the error code

                  A typical callback setup looks like:

                  boost::bind(&Server::handleSend, shared_from_this(),
                                              toSend.at(i),
                                              boost::asio::placeholders::error,
                                              boost::asio::placeholders::bytes_transferred));
                  

                  I mean, I am getting that you are telling me that information simply isn't available to me. So OK, let's accept that. What are you guys doing in your application when an error occurs such as network connection lost?

                  I imagine I'd have to flag each message "sent" when called back without an error callback occurring and retain it until then? The expected callback won't occur at all if the error callback happens, right?

                  For receives, I just won't even know I got anything because I won't be called back until the whole thing arrives, right? I'll just get a network connection lost error and reconnect. The other end will have to handle connection lost.

                  For connect, I suppose I just don't allow sends until the connection callback is called back, in effect making my async call sync.

                  Does that sound like a solid strategy?

                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @Fleshbits If you need to know how many bytes were written you can either use https://doc.qt.io/qt-5/qwebsocket.html#bytesToWrite (you will need to remember how many bytes in total) or use https://doc.qt.io/qt-5/qwebsocket.html#bytesWritten signal.
                  I'm not sure what you are after. You send some data, then error occurs - you do know what data you sent, right? So, you can try to send it again.

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  F 2 Replies Last reply
                  2
                  • jsulmJ jsulm

                    @Fleshbits If you need to know how many bytes were written you can either use https://doc.qt.io/qt-5/qwebsocket.html#bytesToWrite (you will need to remember how many bytes in total) or use https://doc.qt.io/qt-5/qwebsocket.html#bytesWritten signal.
                    I'm not sure what you are after. You send some data, then error occurs - you do know what data you sent, right? So, you can try to send it again.

                    F Offline
                    F Offline
                    Fleshbits
                    wrote on last edited by
                    #9

                    @jsulm said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

                    @Fleshbits If you need to know how many bytes were written you can either use https://doc.qt.io/qt-5/qwebsocket.html#bytesToWrite (you will need to remember how many bytes in total) or use https://doc.qt.io/qt-5/qwebsocket.html#bytesWritten signal.
                    I'm not sure what you are after. You send some data, then error occurs - you do know what data you sent, right? So, you can try to send it again.

                    Sounds good.
                    Yea, I just want to confirm the nuances. Thanks.

                    1 Reply Last reply
                    0
                    • jsulmJ jsulm

                      @Fleshbits If you need to know how many bytes were written you can either use https://doc.qt.io/qt-5/qwebsocket.html#bytesToWrite (you will need to remember how many bytes in total) or use https://doc.qt.io/qt-5/qwebsocket.html#bytesWritten signal.
                      I'm not sure what you are after. You send some data, then error occurs - you do know what data you sent, right? So, you can try to send it again.

                      F Offline
                      F Offline
                      Fleshbits
                      wrote on last edited by Fleshbits
                      #10

                      @jsulm This doesn't seem to work as expected.
                      When I connect it tells me it sent 157 bytes, when I disconnect it tells me I sent 6 bytes, when I actually send something, it tells me it sent bytes, but the bytes don't match the length of the message.

                      If I send "Poopy", it tells me 11 bytes were sent.
                      Perhaps that is two bytes per character and one terminating null?

                      I seem to also get random callbacks that it sent 6 bytes.
                      I can't use connected state to disregard all but the actual sends, because these 6 byte callbacks keep occuring randomly while state == connected.

                      Maybe those are heartbeat messages? How can I tell the callback that results from a heartbeat, from one that results from a send?

                      1 Reply Last reply
                      0
                      • Christian EhrlicherC Offline
                        Christian EhrlicherC Offline
                        Christian Ehrlicher
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        I don't see how you can ever rely on any counter which tells you that there are n bytes sent and this is the real truth. There are so many buffers involved, including the switches and others in between that a disconnected socket boils down to start over or, when you got an answer from the other side which explicitly told you what bytes were received, start from there. Everything else is useless.

                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                        Visit the Qt Academy at https://academy.qt.io/catalog

                        F 1 Reply Last reply
                        1
                        • Christian EhrlicherC Christian Ehrlicher

                          I don't see how you can ever rely on any counter which tells you that there are n bytes sent and this is the real truth. There are so many buffers involved, including the switches and others in between that a disconnected socket boils down to start over or, when you got an answer from the other side which explicitly told you what bytes were received, start from there. Everything else is useless.

                          F Offline
                          F Offline
                          Fleshbits
                          wrote on last edited by Fleshbits
                          #12

                          @Christian-Ehrlicher said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

                          I don't see how you can ever rely on any counter which tells you that there are n bytes sent and this is the real truth. There are so many buffers involved, including the switches and others in between that a disconnected socket boils down to start over or, when you got an answer from the other side which explicitly told you what bytes were received, start from there. Everything else is useless.

                          If I don't want to have a connected stream of data with acknowledgements built in, why aren't I using UDP?

                          My understanding was that websockets are built on top of HTTP, which is on top of TCP, which has "SYN" and "ACK" built in.

                          If I have to create my own acknowledgements for every message I send, I might as well drop all the overhead, no?

                          Christian EhrlicherC 1 Reply Last reply
                          0
                          • F Fleshbits

                            @Christian-Ehrlicher said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

                            I don't see how you can ever rely on any counter which tells you that there are n bytes sent and this is the real truth. There are so many buffers involved, including the switches and others in between that a disconnected socket boils down to start over or, when you got an answer from the other side which explicitly told you what bytes were received, start from there. Everything else is useless.

                            If I don't want to have a connected stream of data with acknowledgements built in, why aren't I using UDP?

                            My understanding was that websockets are built on top of HTTP, which is on top of TCP, which has "SYN" and "ACK" built in.

                            If I have to create my own acknowledgements for every message I send, I might as well drop all the overhead, no?

                            Christian EhrlicherC Offline
                            Christian EhrlicherC Offline
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            @Fleshbits said in Qt Socket error handling - How to tell the source of error and operation it occurred in:

                            If I don't want to have a connected stream of data with acknowledgements built in, why aren't I using UDP?

                            Because then you also have to check the order and the complete packet.
                            With tcp it's guaranteed that the client receives all data, with the correct order. But noone can tell you which bytes the client received when the connection is lost (for whatever reason). Only the client can tell this to you.

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            1 Reply Last reply
                            2

                            • Login

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