Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-interest Archive, December 2006
QTcpSocket thread problems( Mingw 4.2.2 )


Message 1 in thread

Hi all,
How can I send data through a QTcpSocket running in a separated thread 
from the main thread?
I works fine when I'm using Qt 4.1.1 in Visual Studio, but the same code 
shows the message "QSocketNotifier: socket notifiers cannot be enabled 
from another thread" whenever I send data via qtcpsocket.write(...) when 
compiled with Qt 4.2.2 and Mingw. Does somebody knows why this is 
happening?
Thanks again,
     Bruno.

--
 [ signature omitted ] 

Message 2 in thread

Hi,

> I works fine when I'm using Qt 4.1.1 in Visual Studio, but the same code 
> shows the message "QSocketNotifier: socket notifiers cannot be enabled 
> from another thread" whenever I send data via qtcpsocket.write(...) when 
> compiled with Qt 4.2.2 and Mingw. Does somebody knows why this is 
> happening?

Are you certain you don't get the same message with the exact same 
source code under Visual Studio? Where does this message appear with MinGW?

--
 [ signature omitted ] 

Message 3 in thread

Hi Dimitri,
Follow below the class that extends QThread and has the QTcpSocket:

void Com::run()
{
    tcpSocket=new QTcpSocket();
    connect( tcpSocket, SIGNAL( disconnected() ), this, SLOT(
disconnectedFromServer() ) );
    connect( tcpSocket, SIGNAL( connected() ), this, SLOT(
connectedTotServer() ) );
    connect( tcpSocket, SIGNAL( readyRead() ), this, SLOT(
readDataFromServer() ) );
    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
SLOT(error(QAbstractSocket::SocketError)));
    tcpSocket->connectToHost( ipserver,port);
    exec();
}
void Com::sendToServer( QMultiHash<QString, QByteArray> &hash)
{
    if(!tcpSocket)return;
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
    out << (qint64)0;
    out <<hash;
    out.device()->seek(0);
    out << (qint64)(block.size() - sizeof(qint64));
    qint64 totalSize=block.size();
    qint64 totalBytesWritten=0;
    qint64 bytesWritten=0;
    tcpSocket->write(block);
}

After tcpSocket connects, I get a signal in the class MainWindow running
in the main thread. Then I try
to send some data. The exactly same code works over Qt 4.1.1 and Visual
Studio 2005,
but it doesn't in Qt 4.2.2 and Mingw. If I remove the line
com->sendToServer(...) below, I don't get the error
"QSocketNotifier: socket notifiers cannot be enabled from another
thread". Nothing is received by the server.

void MainWindow::connectedToServer() (slot)
{
        QMultiHash<QString, QByteArray> hashOut;
        hashOut.insert("test", QString("testonly").toLatin1());
        com->sendToServer(hashOut);
}
Dimitri wrote:
> Hi,
>
>> I works fine when I'm using Qt 4.1.1 in Visual Studio, but the same 
>> code shows the message "QSocketNotifier: socket notifiers cannot be 
>> enabled from another thread" whenever I send data via 
>> qtcpsocket.write(...) when compiled with Qt 4.2.2 and Mingw. Does 
>> somebody knows why this is happening?
>
> Are you certain you don't get the same message with the exact same 
> source code under Visual Studio? Where does this message appear with 
> MinGW?
>
> -- 
> Dimitri
>
> -- 
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with 
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
>


--
 [ signature omitted ] 

Message 4 in thread

Hi Dimitri,
I created this simple class below to illustrate the problem. It also 
shows the message "QSocketNotifier: socket notifiers cannot be enabled 
from another thread" when it calls sendMessage("test") over Qt 4.2.2 and 
Mingw.
Any ideas? Please!!! :-)

TcpClient::TcpClient(const QString &host, int port)
{
    this->port=port;
    this->host=host;
    start();
}
void TcpClient::run()
{
    tcpSocket=new QTcpSocket();   
    connect( tcpSocket, SIGNAL( connected() ), this, SLOT( connected() ) 
);   
    tcpSocket->connectToHost( host,port);       
    exec();
}
void TcpClient::connected()
{   
    sendMessage("test");
}
void TcpClient::sendMessage(const QString &message)
{
    tcpSocket->write(message.toLatin1().data());
}

-----------------
Bruno Tezine wrote:
> Hi Dimitri,
> Follow below the class that extends QThread and has the QTcpSocket:
>
> void Com::run()
> {
>    tcpSocket=new QTcpSocket();
>    connect( tcpSocket, SIGNAL( disconnected() ), this, SLOT(
> disconnectedFromServer() ) );
>    connect( tcpSocket, SIGNAL( connected() ), this, SLOT(
> connectedTotServer() ) );
>    connect( tcpSocket, SIGNAL( readyRead() ), this, SLOT(
> readDataFromServer() ) );
>    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
> SLOT(error(QAbstractSocket::SocketError)));
>    tcpSocket->connectToHost( ipserver,port);
>    exec();
> }
> void Com::sendToServer( QMultiHash<QString, QByteArray> &hash)
> {
>    if(!tcpSocket)return;
>    QByteArray block;
>    QDataStream out(&block, QIODevice::WriteOnly);
>    out.setVersion(QDataStream::Qt_4_0);
>    out << (qint64)0;
>    out <<hash;
>    out.device()->seek(0);
>    out << (qint64)(block.size() - sizeof(qint64));
>    qint64 totalSize=block.size();
>    qint64 totalBytesWritten=0;
>    qint64 bytesWritten=0;
>    tcpSocket->write(block);
> }
>
> After tcpSocket connects, I get a signal in the class MainWindow running
> in the main thread. Then I try
> to send some data. The exactly same code works over Qt 4.1.1 and Visual
> Studio 2005,
> but it doesn't in Qt 4.2.2 and Mingw. If I remove the line
> com->sendToServer(...) below, I don't get the error
> "QSocketNotifier: socket notifiers cannot be enabled from another
> thread". Nothing is received by the server.
>
> void MainWindow::connectedToServer() (slot)
> {
>        QMultiHash<QString, QByteArray> hashOut;
>        hashOut.insert("test", QString("testonly").toLatin1());
>        com->sendToServer(hashOut);
> }
> Dimitri wrote:
>> Hi,
>>
>>> I works fine when I'm using Qt 4.1.1 in Visual Studio, but the same 
>>> code shows the message "QSocketNotifier: socket notifiers cannot be 
>>> enabled from another thread" whenever I send data via 
>>> qtcpsocket.write(...) when compiled with Qt 4.2.2 and Mingw. Does 
>>> somebody knows why this is happening?
>>
>> Are you certain you don't get the same message with the exact same 
>> source code under Visual Studio? Where does this message appear with 
>> MinGW?
>>
>> -- 
>> Dimitri
>>
>> -- 
>> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx 
>> with "unsubscribe" in the subject or the body.
>> List archive and information: http://lists.trolltech.com/qt-interest/
>>
>>
>>
>
>
> -- 
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with 
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
>

--
 [ signature omitted ] 

Message 5 in thread

Am Mittwoch, 6. Dezember 2006 18:31 schrieb Bruno Tezine:
> Hi Dimitri,
> I created this simple class below to illustrate the problem. It also
> shows the message "QSocketNotifier: socket notifiers cannot be enabled
> from another thread" when it calls sendMessage("test") over Qt 4.2.2 and
> Mingw.
The problem is more or less obviously. You're using queued-connections which 
will make connected() being called with affinity of the GUI-thread (as it 
belongs to your thread-class which has been created there) and therefore will 
give the errors you described. Qt 4.1.x hasn't been that strict that's why it 
probably worked but with Qt 4.2.x. you've to be more carefully.

Try to use

connect( tcpSocket, SIGNAL( connected() ), this, SLOT( connected() ), 
Qt::DirectConnection );

toby

Attachment:

Attachment: pgpavrOwbieCe.pgp
Description: PGP signature


Message 6 in thread

Hey, thanks.
Now it works, but now appears a second problem. How can I send some data 
from the main thread? :-P

Tobias Doerffel wrote:
> Am Mittwoch, 6. Dezember 2006 18:31 schrieb Bruno Tezine:
>   
>> Hi Dimitri,
>> I created this simple class below to illustrate the problem. It also
>> shows the message "QSocketNotifier: socket notifiers cannot be enabled
>> from another thread" when it calls sendMessage("test") over Qt 4.2.2 and
>> Mingw.
>>     
> The problem is more or less obviously. You're using queued-connections which 
> will make connected() being called with affinity of the GUI-thread (as it 
> belongs to your thread-class which has been created there) and therefore will 
> give the errors you described. Qt 4.1.x hasn't been that strict that's why it 
> probably worked but with Qt 4.2.x. you've to be more carefully.
>
> Try to use
>
> connect( tcpSocket, SIGNAL( connected() ), this, SLOT( connected() ), 
> Qt::DirectConnection );
>
> toby
>   

--
 [ signature omitted ] 

Message 7 in thread

Am Mittwoch, 6. Dezember 2006 19:04 schrieb Bruno Tezine:
> Hey, thanks.
> Now it works, but now appears a second problem. How can I send some data
> from the main thread? :-P
You would have to enqueue them somehow. But if you create a separate thread 
for processing your socket you have to deal with everything concerning the 
socket within your thread, otherwise the whole thing makes do sense and you 
can do everything via the main-thread. Normally you use threads in 
combination with sockets when writing a server-application. In such an 
application each thread would deal with one client and everything is fine ;-)

toby

Attachment:

Attachment: pgpb7LIY8hg5a.pgp
Description: PGP signature


Message 8 in thread

Hello

you can use a queue and write data from one thread, and read them with 
the other and maybee use a mutex

or you can use signals and slots to send data from one thread to the other

Loïc


Bruno Tezine a écrit :
> Hey, thanks.
> Now it works, but now appears a second problem. How can I send some data 
> from the main thread? :-P
> 
> Tobias Doerffel wrote:
>> Am Mittwoch, 6. Dezember 2006 18:31 schrieb Bruno Tezine:
>>  
>>> Hi Dimitri,
>>> I created this simple class below to illustrate the problem. It also
>>> shows the message "QSocketNotifier: socket notifiers cannot be enabled
>>> from another thread" when it calls sendMessage("test") over Qt 4.2.2 and
>>> Mingw.
>>>     
>> The problem is more or less obviously. You're using queued-connections 
>> which will make connected() being called with affinity of the 
>> GUI-thread (as it belongs to your thread-class which has been created 
>> there) and therefore will give the errors you described. Qt 4.1.x 
>> hasn't been that strict that's why it probably worked but with Qt 
>> 4.2.x. you've to be more carefully.
>>
>> Try to use
>>
>> connect( tcpSocket, SIGNAL( connected() ), this, SLOT( connected() ), 
>> Qt::DirectConnection );
>>
>> toby
>>   
> 
> -- 
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with 
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/

--
 [ signature omitted ] 

Message 9 in thread

On Tuesday 05 December 2006 00:21, Bruno Tezine wrote:
> I works fine when I'm using Qt 4.1.1 in Visual Studio, but the same code
> shows the message "QSocketNotifier: socket notifiers cannot be enabled
> from another thread" whenever I send data via qtcpsocket.write(...) when
> compiled with Qt 4.2.2 and Mingw. Does somebody knows why this is
> happening?

AFAIK you need to create the socket in the same thread as it was created in. 
Are you sure you are doing that?

Also 4.1.1 is a bit old. Does it also happen with 4.2.2?


	Konrad

Attachment:

Attachment: pgpyp5iinFsMd.pgp
Description: PGP signature


Message 10 in thread

Hi,

On Tuesday 05 December 2006 19:03, Bruno Tezine wrote:
> Hi Konrad,
> Actually it only happens on Qt 4.2.2 with Mingw. It does not happen over
> Qt 4.1.1 and Visual Studio 2005.
> Exactly the same code works over Qt 4.1.1 and Visual Studio.
> Follow below the class that extends QThread and has the QTcpSocket:
>
> After tcpSocket connects, I get a signal in the class MainWindow running
> in the main thread. Then I try
> to send some data. If I remove the line com->sendToServer(...) below, I
> don't get the error
> "QSocketNotifier: socket notifiers cannot be enabled from another
> thread". Nothing is received by the server.

I think from this it is pretty clear what happened: your sendToServer method 
gets called from the main thread instead of the Com:: thread.

This is what I usually do:

Create a class derived from QThread that only overwrites run() and 
instantiates a "Driver" class. The Driver class then instantiates the 
socket and handles the communication in its slots.

This way:

a) you avoid the confusion caused by the thread class being part of the 
thread that instantiated it(*), instead of the one it runs itself

b) by handling stuff in the slots you can make sure that everything happens 
in the right thread (by using queued connections)

(*) visualise the thread class as a supervisor of the thread, not as the 
thread itself


	Konrad

Attachment:

Attachment: pgpDEHYOcdTyl.pgp
Description: PGP signature


Message 11 in thread

Tuesday 05 December 2006 00:21 Bruno Tezine wrote:
> Hi all,
> How can I send data through a QTcpSocket running in a separated thread
> from the main thread?
> I works fine when I'm using Qt 4.1.1 in Visual Studio, but the same code
> shows the message "QSocketNotifier: socket notifiers cannot be enabled
> from another thread" whenever I send data via qtcpsocket.write(...) when
> compiled with Qt 4.2.2 and Mingw. Does somebody knows why this is
> happening?

The easiest for you to do is simply to access the socket through a signal. 
This way the Qt event system will deliver the signal to the slot in the right 
thread.

Bo.

-- 
 [ signature omitted ]