PDA

View Full Version : socket in thread error!



alphaboy
14th November 2007, 14:22
Dear everybody!

now I'm using socket in thread!

in the thread:
//////////////////

if (!tcpSocket.setSocketDescriptor(socketDescriptor))
{
emit error(tcpSocket.error());
return;
}

tcpSocket.waitForReadyRead();

QByteArray Mark = tcpSocket.read(10);

//////////////////
when the program was ran the error is reported!

cannot send events to objects owned by a different thread!

when I remove the "tcpSocket.waitForReadyRead();",the error isn't appear,but I cannot get any data form socket!

high_flyer
14th November 2007, 14:45
can you show more of your code?
your signal slot connection lines, and your and your QThread subclass run().

Valheru
14th November 2007, 17:03
No need to show the code, I recognize the error :p


To get it to work, you are going to have to subclass QTcpSocket, and then in the run() method of the subclassed QThread create it, so that it lives only in that QThread.

Put all the code that connects the signals and slots in the constructor of the subclassed QTcpSocket, and handle all readyReads() and such in the subclassed QTcpSocket as well.

alphaboy
15th November 2007, 01:22
Thank you very much!

I post the code now.my English is not good,so I can't understand very well.Can you show me an example?

Here is my code!

void socketThread::run()
{

if (!tcpSocket.setSocketDescriptor(socketDescriptor))
{
emit error(tcpSocket.error());
return;
}

tcpSocket.waitForReadyRead();

while(true)
{

if (tcpSocket.bytesAvailable()>0)
{
QByteArray Mark = tcpSocket.read(10);

if (Mark == gc_Mark)
{
QByteArray CmdType =tcpSocket.read(1);

switch (CmdType.at(0))
{
case Configure:
parserSendConfig();
break;
case LogRequest:
upCurrentLog();
break;
case TimeAdjust:
setTime();
break;
default:
;
}

}
}

}

}

high_flyer
15th November 2007, 09:47
There are two things that jump right away, so I'll start with those.
It could be however you have other problems in there as well.

The first thing is that you don't need to use an endless while loop, but can use the QTcpSocket readyRead() signal.
This is not a problem on its on, just a cleaner way to do it.

The other problem, is the thread affinity.
Please read the docs about threading in Qt, specially this section (http://doc.trolltech.com/4.3/threads.html#per-thread-event-loop)about thread affinity.

Basically, only objects allocated IN the run() method will have the thread class affinity (of the non GUI thread) - and your 'tcpSocket' object is allocated outside the run() function, in the main GUI thread, which is the reason you get the error you reported.

Valheru
15th November 2007, 14:47
Not only that, but if you want to use Qt's signals and slot mechanism, you HAVE to call exec() in the threads run() method otherwise the thread has no event loop. (Well, I suppose you could implement an event loop yourself but that yould be nasty :p ). So ditch the while loop and jsut call exec() in the thread's run() method. Handle all of the signal's emitted by the socket in socket.cpp (or whatever the name of your subclassed QTcpSocket is). Connect all the signals and slots in the constructor of your QTcpSocket subclass (or in the run() method of your thread, but personally I find that messy). I can't get any clearer than that :p

If you want an example, see http://knewz.svn.sourceforge.net/viewvc/knewz/trunk/src/ Look at the classes connection.h/cpp and socket.h/cpp and see how I implemented this there.

alphaboy
18th November 2007, 12:15
Tanks very much! the program is solved!

I have learned how to use even in thread!

:p

Thanks everyone!