non blocking threaded tcp client
-
Hello there,
Please let me explain what is my problem:
I have a Gui application, that has to connect to remote server and keep connected to it for the time untill a user decides to quit the connection, or the server will. I wish to create the client connection mechanism in a separate thread. If the client should be able to asynchronusly receive data and in event driven style inform the main gui thread about it. The thread should also be able to receive data from gui thread to be sent to the server.I come from a low level microcontroller place, where I would handle this task simply using interrupts and while(1) loop and flags. The problem is on a pc, this would take to much processor time. I have watched and read a lot of tutorials about sockets and threads in qt, but i still dont know what is the best aproach and how to do it properly.
For now, I have a test server on a remote target that is able to receive connections from my Qt client that I am trying to write. I have a class now for my client in Qt, that inherits from Qthread, but then I read that it is not the best aproach anymore.
I wish to create a client instance in new thread (triggered from the gui thread) that will hang forever with exec(). Now I dont know how to handle, using signals the incoming data from the server and incoming commands from the main GUI thread. In general, I would maybe know how to implement this on a low level, but i read about a lot of high level functions for this that qt delivers, i wish to use that.I would really aprichiate help in this matter. I tried searching, but havent found any solid, working up to date code examples. Could someone please explain me how to create a client instannce in a new thread that wont disconnect after sending/ receiving some data, but instead stay connected and stay responsive to to server calls and gui thread calls in event driven style?
-
Hi,
Technically from a client side view, you generally don't need a thread using QTcpClient. It's use is already asynchronous. So do you really want that thread ? If so, encapsulate your QTcpSocket in a worker object that will to all the processing your need before sending the data to your GUI. Then just create a QThread, move that worker object to it and start the thread.
Hope it helps
-
-
You don't need nor want an infinite loop. QThread already spins its own event loop after you call start. In any case, do you really need that secondary thread ?
-
@SGaist now I know that it does. I figured out that I need to call exec() at the end of the run method. Now
I need the second thread because the main gui thread migh be blocking (modal windows can pop etc), and there will be data coming asynchronously.
At ths point my model works like this:
Create a new thread and pass ip and port to the constructor
At the beginning of run function try to connect to server and connect connected, disconnected slots.
Call exec()The only thing Im not sure about how to do now is the communication between main thread and created one.
-
A blocking dialog doesn't mean that your application stops processing everything. There's even the open method of QDialog that will let you properly run the event loop.
You can do the communication using signals and slots.
-
@SGaist i wish to do this using signals and slots, but with addition of connectings tose signals and slots through different threads. The application will grow, I want to separate tasks in a clean way. Why are you so much agains it, its a common thing to do it?
-
Separating responsibilities and encapsulation sure are the thing to do, no doubt about that. However that doesn't mean putting everything in its own thread. Threading is a complex subject and it's not always a performance boost (some times it's even the contrary) Also, Qt's network stack is already asynchronous thus the common cases don't require any threading at all.
If you encapsulate your network functionality properly, then putting it in a thread would only require you to use the worker object approach described in QThread's documentation
-
@SGaist, QTcpServer do support asynchronous operations, but is it possible to dispatch the task to different thread just like the boost::asio did?The Qt example(Threaded fortune server?) have a solution of combining the QThread and asynchronous api together, but I do not think it is suit for large scale connection(open 10000 thread within 1 seconds? almost impossible). I think a better solution should be create a thread pool, and dispatch the tasks to different thread.
But I do not know it well, if you want to combine asynchronous api with threads, maybe you can give threadWeaver a try?This lib looks promising(tech preview of Qt3d2.0 use it internally), but I do not know it very well yet.
-
@stereomatchingkiss Indeed, such a huge amount of connections in such a short time would rather need a thread pool, otherwise you're going to starve your system.