How to do it…

Follow these steps to create a TCP server:

  1. First, let's create a Qt Console Application project from File | New File or Project, as shown in the following screenshot:

  1. After that, go to File | New File or Project again. But this time, select C++ Class under the C++ category, as shown in the following screenshot:

  1. Then, name your class as server. Set its base class to QObject and make sure the Include QObject option is checked before clicking the Next button. Once the class has been created, two files will be created for you—server.h and server.cpp, as shown in the following screenshot:

  1. After that, open up your project file (.pro) and add in the network module, as shown in the following code:
QT += core network
  1. Once you're done, open up server.h and add the following headers to it:
#include <QTcpServer>
#include <QTcpSocket>
#include <QVector>
#include <QDebug>

  1. Right after that, declare startServer() and sendMessageToClients() functions, as shown in the following code:
public:
server(QObject *parent = nullptr);
void startServer();
void sendMessageToClients(QString message);
  1. Then declare the following slot functions for the server class:
public slots:
void newClientConnection();
void socketDisconnected();
void socketReadReady();
void socketStateChanged(QAbstractSocket::SocketState state);
  1. Finally, declare two private variables, as shown in the following code:
private:
QTcpServer* chatServer;
QVector<QTcpSocket*>* allClients;
  1. Once you're done with the preceding step, open up server.cpp and define the startServer() function. Here, we create a QVector container to store all the clients that are connected to the server and use it to send out messages in later steps. This is shown in the following example:
void server::startServer() {
allClients = new QVector<QTcpSocket*>;
chatServer = new QTcpServer();
chatServer->setMaxPendingConnections(10);
connect(chatServer, &QTcpServer::newConnection, this, &server::newClientConnection);
if (chatServer->listen(QHostAddress::Any, 8001))
qDebug() << "Server has started. Listening to port 8001.";
else
qDebug() << "Server failed to start. Error: " + chatServer->errorString();
}

  1. Next, we implement the sendMessageToClients() function, where we iterate through the allClients container we just created in the previous step, and send the message to each of them, as shown in the following example:
void server::sendMessageToClients(QString message) {
if (allClients->size() > 0) {
for (int i = 0; i < allClients->size(); i++) {
if (allClients->at(i)->isOpen() && allClients->at(i)->isWritable()) {
allClients->at(i)->write(message.toUtf8());
}
}
}
}
  1. After that, we will start implementing the slot functions. Let's start off with the following code:
void server::newClientConnection() {
QTcpSocket* client = chatServer->nextPendingConnection();
QString ipAddress = client->peerAddress().toString();
int port = client->peerPort();
connect(client, &QTcpSocket::disconnected, this, &server::socketDisconnected);
connect(client, &QTcpSocket::readyRead,this, &server::socketReadReady);
connect(client, &QTcpSocket::stateChanged, this, &server::socketStateChanged);
allClients->push_back(client);
qDebug() << "Socket connected from " + ipAddress + ":" + QString::number(port);
}
  1. Then, we'll proceed with the socketDisconnected() function. This slot function will be called when a client has been disconnected from the server, as shown in the following example:
void server::socketDisconnected() {
QTcpSocket* client = qobject_cast<QTcpSocket*>(QObject::sender());
QString socketIpAddress = client->peerAddress().toString();
int port = client->peerPort();
qDebug() << "Socket disconnected from " + socketIpAddress + ":" + QString::number(port);
}

  1. Next, we'll define the socketReadReady() function, which will be triggered when a client is sending in a text message to the server, as shown in the following example:
void server::socketReadReady() {
QTcpSocket* client = qobject_cast<QTcpSocket*>(QObject::sender());
QString socketIpAddress = client->peerAddress().toString();
int port = client->peerPort();
QString data = QString(client->readAll());
qDebug() << "Message: " + data + " (" + socketIpAddress + ":" + QString::number(port) + ")";
sendMessageToClients(data);
}
  1. After that, let's implement the socketStateChanged() function, which will be called when the networking state of a client has changed, as shown in the following example:
void server::socketStateChanged(QAbstractSocket::SocketState state) {
QTcpSocket* client = qobject_cast<QTcpSocket*>(QObject::sender());
QString socketIpAddress = client->peerAddress().toString();
int port = client->peerPort();

qDebug() << "Socket state changed (" + socketIpAddress + ":" + QString::number(port) + "): " + desc;
}
  1. We also need to add the following code into socketStateChanged() to print out the status of the client:
QString desc;
if (state == QAbstractSocket::UnconnectedState)
desc = "The socket is not connected.";
else if (state == QAbstractSocket::HostLookupState)
desc = "The socket is performing a host name lookup.";
else if (state == QAbstractSocket::ConnectingState)
desc = "The socket has started establishing a connection.";
else if (state == QAbstractSocket::ConnectedState)
desc = "A connection is established.";
else if (state == QAbstractSocket::BoundState)
desc = "The socket is bound to an address and port.";
else if (state == QAbstractSocket::ClosingState)
desc = "The socket is about to close (data may still be waiting to be written).";
else if (state == QAbstractSocket::ListeningState)
desc = "For internal use only.";
  1. Lastly, let's open up main.cpp, and add the highlighted code in the following example in order to initiate the server:
#include <QCoreApplication>
#include "server.h"

int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
server* myServer = new server();
myServer->startServer();
return a.exec();
}
  1. You can try and run the server program now, but you won't be able to test it as we have not created the client program yet, as the following screenshot shows:

  1. Let's proceed to the next example project and learn how to create the client program. We will come back to test this program again later on.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset