Anslem
1st June 2014, 16:10
I am developing a simple program, a sever\client file manager. I use threads in that program and i ran into this problem.
// this class is responsible for making connection with a server and sending it a command
class CommandSender : public QObject
{
Q_OBJECT
public:
...
QTcpSocket* socketToServer;
QTcpSocket* connectToServer(const Command* command);
...
}
1)"connectToServer" establishes a conenction with a server, sends it a command that was passed as a parameter and returns
a connected socket ready to recieve a reply from the server.
2) Command class is a base class for all commands that a client can send to a server, for exeample - DownloadCommand. Basically, all command classes
have a funtion "QString GetCommandString()", not important here.
3) Every command class has a Runnable analog, i.e there is DownloadCommand and there is DownloadCommandRunnable. For QThreadPool usage.
Now, this is a main GUI thread function:
void MainWindow::on_actionDownload_triggered()
{
...
DownloadCommandRunnable *command = new DownloadCommandRunnable();
threadPool->start(command);
}
void DownloadCommandRunnable::run()
{
DownloadCommand command;
CommandSender sender;
// socketToReceiveFile is a DownloadCommandRunnable class' member field
socketToReceiveFile = sender.loadServerFileHierarchy(&command);
connect(this, SIGNAL(readyToWork()), this, SLOT(start()));
emit readyToWork();
// start an event loop
}
void DownloadCommandRunnable::start()
{
socketToReceiveFile->write("ready to receive file"); // this is the point of interest
}
When i send that string to a server i get this warning:
QSocketNotifier: socket notifiers cannot be enabled from another thread
I searched the internet for an answer and it seems like this message appears when socket is created in one thread and being used in another.
Thing is, "socketToReceiveFile" is a member field of CommandSender, that is created in the "run" function. That means that i'm trying to use the "write" function in the thread where "socketToReceiveFile" was created.
I got rid of that message using this code:
void DownloadCommandRunnable::start()
{
QTcpSocket* socket = new QTcpSocket();
socket->setSocketDescriptor(socketToReceiveFile->socketDescriptor());
socket->write("ready to receive file");
}
But i can't understand why it works like that. Both "socketToReceiveFile" and "socket" are created in the same thread, but one gives me an error and the other works just fine.
// this class is responsible for making connection with a server and sending it a command
class CommandSender : public QObject
{
Q_OBJECT
public:
...
QTcpSocket* socketToServer;
QTcpSocket* connectToServer(const Command* command);
...
}
1)"connectToServer" establishes a conenction with a server, sends it a command that was passed as a parameter and returns
a connected socket ready to recieve a reply from the server.
2) Command class is a base class for all commands that a client can send to a server, for exeample - DownloadCommand. Basically, all command classes
have a funtion "QString GetCommandString()", not important here.
3) Every command class has a Runnable analog, i.e there is DownloadCommand and there is DownloadCommandRunnable. For QThreadPool usage.
Now, this is a main GUI thread function:
void MainWindow::on_actionDownload_triggered()
{
...
DownloadCommandRunnable *command = new DownloadCommandRunnable();
threadPool->start(command);
}
void DownloadCommandRunnable::run()
{
DownloadCommand command;
CommandSender sender;
// socketToReceiveFile is a DownloadCommandRunnable class' member field
socketToReceiveFile = sender.loadServerFileHierarchy(&command);
connect(this, SIGNAL(readyToWork()), this, SLOT(start()));
emit readyToWork();
// start an event loop
}
void DownloadCommandRunnable::start()
{
socketToReceiveFile->write("ready to receive file"); // this is the point of interest
}
When i send that string to a server i get this warning:
QSocketNotifier: socket notifiers cannot be enabled from another thread
I searched the internet for an answer and it seems like this message appears when socket is created in one thread and being used in another.
Thing is, "socketToReceiveFile" is a member field of CommandSender, that is created in the "run" function. That means that i'm trying to use the "write" function in the thread where "socketToReceiveFile" was created.
I got rid of that message using this code:
void DownloadCommandRunnable::start()
{
QTcpSocket* socket = new QTcpSocket();
socket->setSocketDescriptor(socketToReceiveFile->socketDescriptor());
socket->write("ready to receive file");
}
But i can't understand why it works like that. Both "socketToReceiveFile" and "socket" are created in the same thread, but one gives me an error and the other works just fine.