Unsolved Difficulties with QTcpSocket on Windows
-
I'm working on a project, which need handle communications between PC (Windows platform) and a device with TCP/IP. But I encountered some difficulties with Qt.
The work flow is simple: the user press one button, the communication start, when the the user press the button again, the communication stops. In order to response to the user input in communication, and don't 'freeze' the GUI, I choose the blocking approach with QTcpSocket. But the big problem is, all waitForxxxx functions are stated with something like below:
Note: This function may fail randomly on Windows. Consider using the event loop and the connected() signal if your software will run on Windows.
As in the blocking method, all these functions must be called to drive the data flow, this almost kill me!!! So anyone can give some suggestions? Can I continue use socket in a separate thread and bypass the problem on windows? Or there are other methods receive the user input when using the asynchronous (non-blocking) approach. Anyway, I think the blocking one is better, if there is not such problem with windows!!!!!
Best regards.
-
@diverger said:
think the blocking one is better,
It (almost) never is
See http://doc.qt.io/qt-5/qtnetwork-threadedfortuneserver-example.html and http://doc.qt.io/qt-5/qtnetwork-fortuneclient-example.html
-
Thanks for the reply.
I think the threaded one is better here just because I can receive user input in the GUI thread. And the blocking one make me do things 'in sequence'. Or can you give some other method to achieve these goal?
I've seen the example you give. Can the threaded one work on windows without problem?
-
@VRonin
I think the threaded fortune server has a bug for one, "for two" it's a terrible example to begin with.@diverger
You can make the non-blocking code blocking, but why do you think it's blocking operations that you need?Here I suggest looking at an example I've prepared for a library of mine. It's a threaded TCP server, so you can look at it for some inspiration.
Kind regards.
-
@kshegunov :), because the 'blocking one' can be used in a separate thread, though it will blocking, but it won't blocking the GUI. If I choose the asynchronous (non-blocking) one, I will encounter two problem:
- I need jump between the slots, can't do things in sequence.
- Can I accept another input event in the button's event slot?
Um, thanks for your Bitbucket project, can it solve the problem on Windows?
-
@diverger
The non-blocking one can also be used in a separate thread, just as in the butbucket project. Whether you block the control flow or not isn't connected with the threading in any way. As for your problems:- You don't need to do the things in sequence, that's what even-driven programming is all about. You get an event/signal and respond to that.
- The button's slot is executed in the GUI thread and can accept any input event. Honestly I don't understand what your question is here.
PS.
The example I provided will run fine on any platform that has Qt support, not only on Windows.Kind regards.
-
@kshegunov For 2. My doubt is, if I don't use a separate thread, when user press my button first time, my code execute, and when the button's slot function are executing, the user want to stop the execution, so he press the same button again to try to stop it (my button is designed to a toggle one, just like a tackle switch). Then how can my code respond to the second pressing event when it is running? By polling it?
-
@diverger "Then how can my code respond to the second pressing event" - you just use the same slot. When the user starts the action then you set some kind of flag that you you're processing. When the user clicks same button again you check that flag: if it is set then you know you need to abort processing if not then there is no running processing and you start a new one. All this is only working if your processing isn't blocking.
void MyClass::onButtonClicked() { if (processing) { // Abort processing = false; } else { // Start processing = true; } }
-
@jsulm My code may busy doing something in the slot, such as it is waiting the response from the remote. That's the reason why I want to separate the socket operations into another thread.
The basic flow of my programm is: tell the remote device do someting, then check the execution result, from the result to determine what to do next, then ...., until the final operation is done, or the user choose abort the execution.
-
@diverger That's why you shouldn't wait for the response. With Qt you can do networking asynchronously.
-
@jsulm Yes, but if use aysnchronously (signal/slot, right?). I need send a command in the button slot, then the result is check in the 'readyRead' slot, then I must have some method to inform the code in my button slot, to tell it to do next thing. Any good method?
And different operation have different command, and the result is different too.
-
Hi,
If I understood you correctly, the click on that button should start some sort of machinery that sends a command, then process the answer and reacts accordingly. And on a click to another button that machinery should stop. Is that correct ?
If so, why not make an object that handles that part ? Then your UI should just call start and stop on that object.
-
@SGaist Actually, it's a 'checkable' pushbutton, first click start the operation, the second click will stop the operation.
-
@diverger
You're describing a finite automaton (also called a finite state machine). It takes a series of inputs and makes a number of (internal) transitions based on the inputs. The UI is just an implementation detail of how the input is provided, it can just as easily be fed through the command line or from a text file.