Re: Wait for thread to complete before reading data?
I'm using a thread to read input from a socket (the reasoning for the thread is when I use socket->waitForReadyRead(-1), it pauses my entire program and prevents another socket from accepting/sending data, which causes it to wait forever). I want to set data with that thread, so I used a SIGNAL/SLOT. The question I have, how can I make sure the data is set before reading from it? I'm looking at mutex locks, but I'm unsure of how to do it.
Here's a basic idea of what I'm doing:
Code:
QList<QByteArray> myList;
QList<QByteArray> MainWindow
::getData(QString cmd
) { thread = new MyThread(cmd);
thread->start();
connect(thread, SIGNAL(dataReady(QList<QByteArray>), this, SLOT(readThreadData(QList<QByteArray>)));
//Lock myList?
return myList;
}
void MainWindow::readThreadData(QList<QByteArray> tList) {
myList = tList;
//Unlock myList?
}
void MainWindow
::loadDataFromList(QString cmd
) { getData(cmd);
//Read from myList?
}
I'm not sure if this is the right approach but I'm not sure how to proceed. I'm sending a command to a program and I wait for input on a socket. The problem is, the program responds to another socket first and then responds to my request.
SockA -> Program
Program -> SockB
SockB -> SOMEWANSOCKET
SOMEWANSOCKET -> SockB
SockB -> Program
Program -> SockA
SockA/SockB are internal to my software. Program is an application I'm communicating with and SOMEWANSOCKET is some server software over the WAN I am communicating with.
What I'm getting is:
SockA -> Program
Program -> SockB
... Can't do anything because SockA is in an infinite loop waiting for readyRead().
I never noticed this before because I was doing everything via localhost and noticed it when I introduced the WAN. I hope that makes sense, it does in my head... :crying:
Added after 49 minutes:
Just a side note. The way I had it before, I didn't use threads. I simply created an object from another class that handled the input/output of the socket.
Code:
runCommand = new CommandRunner();
arrayList = runCommand->doRun(cmd);
return arrayList;
So, if I can do this without needing threads, that's fine with me, but I think I'll have to since I have to make sure I receive all the data before trying to parse it. If I lower my waitForReadyRead() times, it still fails as the function returns before the data is finished being sent.
Re: Wait for thread to complete before reading data?
After getting some sleep, I've written a more thorough description of my problem and how I am working with the sockets. This is all pseudo code.
Quote:
SockA -> connect to local service.
SockB -> listen for connection. (localhost:9999)
SockC -> connect to remote service.
SockA -> send 'START on localhost:9999'
LSERVICE -> SockA 'OK'
LSERVICE -> connect to SockB
LSERVICE -> SockB 'INIT'
SockB -> SockC 'LIST'
SockC -> SockB '1234'
SockB -> LSERVICE '1234' (looks up what 1234 is)
LSERVICE -> SockA 'John'
LSERVICE -> SockA 'Q' (could be completely ignored and go straight to the next line)
LSERVICE -> SockA 'Public'
... more commands
I have the following setup:
lsServer QTcpServer (opens port 9999 on localhost)
rsServer QTcpSocket (connects to a remote service)
cmdRunnr QTcpSocket (connects to local service to issue commands)
I need to communicate between the 3 sockets in varying ways. I do not have control of the 'local service' program. lsServer and rsServer are non-threaded classes that read and write to each other's sockets.
For example:
Code:
connect(rsServer, SIGNAL(readyRead()), this, SLOT(readFromRemote()));
readFromRemote() {
input = rsServer->read(4096);
lsServer->write(input);
}
rsServer passes data that it receives to lsServer.
I use cmdRunnr to connect to a local service and use my program as a proxy of sorts to issue commands to a remote host that I'm directly connected to. The problem is, I need a way to wait until a variable is valid before continuing and I need a way to wait for input to return to the socket before continuing.
For example:
Code:
getValidList() {
QList<QByteArray> myList;
myList = getListFromRemote(cmd);
//... do stuff with myList ...
}
cmdRunnr = new CommandRunner(cmd);
cmdRunnr->start();
//... Find a way to get cmdRunnr->runnerList (QList<QByteArray>) ...
return runnerList;
}
in CommandRunner:
runnerCmd = cmd;
}
CommandRunner:run() {
mySocket.connectToHost(localhost, 4351);
//... do I connect()? ...
mySocket->write(runnerCmd);
mySocket->waitForReadyRead(5000);
input = mySocket->read(4096);
//... input should be OK ...
mySocket->waitForReadyRead(5000);
input = mySocket->read(4096);
//... input might be 'John' followed by more information or simply end at that ...
}
The only way I know the data is finished is when the socket disconnects. There are headers I can read to determine if it's DATA or REPLY. I'm in a conundrum and am unsure of how to tackle this problem.