I am writing a server as a Qt console application. I have the server set up to wait for a socket connection, but I also need to allow a user to input commands into the server for managing it. Both are working independently. However, the problem I ran into is that when I’m in a while loop accepting and processing input commands, the server doesn’t accept connections.
I have a Socket class, and in its constructor, I have:
connect(server,SIGNAL(newConnection()),this, SLOT(newConnection()));
Right under that in the constructor, I call a function that has a more in-depth version of this for getting commands from the user:
QTextStream qin(stdin, QIODevice::ReadOnly);
QString usrCmd;
while(usrCmd != "exit" && usrCmd != "EXIT") {
//Get command input and process here
}
Inside newConnection(), I just accept the next connection and then use the socket.
QTcpSocket *serverSocket = server->nextPendingConnection();
How can I make it so the socket can wait for connections and wait for user-inputed commands at the same time?
Problem with your code is because you are blocking event loop with your while loop. So, the solution to your problem is to read from stdin asynchronously. On Linux (and on Mac, I guess), you can use
QSocketNotifierto notify when the data is arrived on stdin, and to read it manually), as per various internet sources.As I am using Windows, I would suggest you to do it in this way (which should work on all platforms):
So, this is the pseudocode. MainAppClass should your existing server class, just edit the constructor to create new thread, and add new slot for processing the data.
Since I wrote simple guidelines how to use QTcpSocket, here is the brief
When you get client
QTcpSocket, connectreadyRead()signal to some slot, and read data fromsender()object. You don’t need to read anything in the constructor.For reading you can use standard
QIODevicefunctions.Note: this is pseudo code, and you may need to change few things (check the state of the stream on reading, save pointer to sockets in some list, subscribe to
disconnected()signal, calllisten()in constructor, check ifQTcpServeris listening, etc).So, you need to have slot
onReadyRead()in your class which will have the following code:Inside
newConnection()you need to connectreadyRead()signal with your slot.