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