Asynchronous TcpServer Share Object between Threads
-
Hello everyone,
I have a TcpServer up and running. As soon as a client connects I create a new socket and when the client is ready, I start my new Thread with the Task I want it to do. Now when I am ready executing and want to write my Task-result to the socket I have to work with Signal&Slots to make the Socket-Thread send my result. But what I want to do is, send the result directly from the Task-Thread. I tried passing the pointer to the socket to the Result-Thread and write to it, but this only gives me a Warning on runtime: QObject: Cannot create children for a parent that is in a different thread. (Parent is QNativeSocketEngine(0x11d7b10), parent's thread is QThread(0xfa9f40), current thread is QThread(0x101cac0). So maybe you can help me avoid Signals&Slots here.So this is the Method for creating the Socket:
@
void MyClient::CreatSocket(qintptr handle)
{
socket = new QTcpSocket(this);socket->setSocketDescriptor(handle); connect(socket, SIGNAL(connected()), this, SLOT(connected())); connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected())); connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
}
@and here I create the new Task as soon as the Client is ready, and give it the socket.
@
void MyClient::readyRead()
{
task = new MyTask();
task->setAutoDelete (true);task->SetSocket(socket); task->SetFilename(FileName); QThreadPool::globalInstance()->start(task);
}
@This is the Set Socket Function:
@
void MyTask::SetSocket(QTcpSocket *socket)
{
socket = socket;
}
@and last but not least the run Method of MyTask:
@
void MyTask::run()
{
QString non = "This is Sparta!!!!";if(socket->isWritable()) { int written = socket->write(non.toUtf8()); if(written == -1) { qWarning() << "Data could not be written to Socket!"; } else { qDebug()<<"Non written to Socket"; } } else { qWarning() << "Socket is not writable!"; }
@
Thank you in advance! :)
-
Thanks for your reply!
Yes the reason is I'm lazy ;) In my Task-Thread I look at what the Client send me and check if he wants something back, when he wants something I have to send it like here:
"tmp" is the string I get from the socket/client.@
if(tmp.contains("newcycle"))
{
tmp = tmp.replace("newcycle;","\n");
WriteData(tmp);
}
else if (tmp.contains("write"))
{
tmp = tmp.replace("write,","");
WriteData(tmp);
}
else if (tmp.contains("get_x_pos"))
{
emit send_x_pos();
}
else if(tmp.contains("get_y_pos"))
{
emit send_y_pos();
}
else if(tmp.contains("get_z_pos"))
{
emit send_z_pos();
}
@And I have a huge amount of these "get_something" and "set_something"
and for every command I want to receive from the client I have to implement a Signal&Slot. Would make live much easier if I could send back the data right in the Task-Thread instead of emitting the signal.And I am open for a complete redesign of my mechanism if that would make adding these "If(tmp.contains(...))" easy:D
-
Try changing the ownership of serversocket. I have not tried this. It should work. You can use myObject->moveToThread(...)
-
You could simply make one slot
@void sendData(QString)@
and one signal
@void dataReady(QString)@
and in your worker, determine what the string needs to be and emit dataReady.
[quote author="buggi" date="1390469097"]Thanks for your reply!
Yes the reason is I'm lazy ;) In my Task-Thread I look at what the Client send me and check if he wants something back, when he wants something I have to send it like here:
"tmp" is the string I get from the socket/client.@
if(tmp.contains("newcycle"))
{
tmp = tmp.replace("newcycle;","\n");
WriteData(tmp);
}
else if (tmp.contains("write"))
{
tmp = tmp.replace("write,","");
WriteData(tmp);
}
else if (tmp.contains("get_x_pos"))
{
emit send_x_pos();
}
else if(tmp.contains("get_y_pos"))
{
emit send_y_pos();
}
else if(tmp.contains("get_z_pos"))
{
emit send_z_pos();
}
@And I have a huge amount of these "get_something" and "set_something"
and for every command I want to receive from the client I have to implement a Signal&Slot. Would make live much easier if I could send back the data right in the Task-Thread instead of emitting the signal.And I am open for a complete redesign of my mechanism if that would make adding these "If(tmp.contains(...))" easy:D[/quote]