[Qt-interest] QTcpSocket.

Bradley T. Hughes bradley.hughes at nokia.com
Mon Mar 2 14:18:39 CET 2009


Shabd Swarup V wrote:
> Hi,
> 
> I am trying to read data off a socket on localhost and I'm using netcat
> (nc) to simulate the server and to send messages on a particular socket.
> 
> Following is the code snippet:
> 
> /**
> * Thread to detect socket data.
>  *
>  */
> void Communicator::run()
> {
[snip]
> 
>                 connect(socket, SIGNAL(readyRead()), this,
> SLOT(readSocketData()));

So, you are connecting the socket's signal to the QThread subclasses 
readSocketData() slot. Be aware that your slot will be called by the main() 
thread, not your Communicator thread (because QThread has affinity to the 
thread that created the instance, not to itself).

> /**
>  * Read data available on the socket.
>  */
> 
> void Communicator::readSocketData()
[snip]
> 
> Through this code, I am unable to capture the data from the socket, even
> though the connection is made. Please correct me.

Several things:

1. You don't need a thread to do asynchronous networking, Qt supports this 
out-of-the-box already without the need to complicate things with threads.

If you *must* use a thread, despite the above, then there are several things 
to watch out for:

2. QThread is not affine to itself, but to the thread that created it (so 
connecting a QTcpSocket signal to a QThread subclasses slot is crossing 
thread boundaries and will cause concurrent access problems).
3. For QTcpSocket to be able to emit its signals, you have to run the 
eventloop in your thread. You do this by calling QThread::exec() in your run 
reimplementation. Note that QThread::run()'s default implementation does 
this starting with Qt 4.4.
4. I would recommend against subclassing QThread and suggest that you 
subclass QObject instead. This makes your class more general and easier to 
reuse. Like I mentioned above, you don't have to complicate things by 
subclassing QThread. If you *absolutely* must use threads, then this can be 
achieved by doing something like this:

     Communicator *c = new Communicator(...);
     QThread *thread = new QThread(this);
     c->moveToThread(thread);
     connect(c, SIGNAL(finished()), thread, SLOT(quit()));
     thread->start();

-- 
Bradley T. Hughes (Nokia-D-Qt/Oslo), bradley.hughes at nokia.com
Sandakervn. 116, P.O. Box 4332 Nydalen, 0402 Oslo, Norway



More information about the Qt-interest-old mailing list