📜 ⬆️ ⬇️

Simple Qt / C ++ Server

Recently, very often you have to listen to a certain port, receive data from a client and send the appropriate response. I decided to share with newbies how to create such a server and solve some questions posed.
In this article we will look at:
- Creating a TCP server.
- Connect multiple clients to the server in parallel.
- Disable clients (disable sockets).
- Receive and send data.

Sources: https://github.com/valualit/QTcpServer01

image
')

QTcpServer or listening to the right port

In the variable server_status - I keep the status of QTcpServer so that there are no excesses during server operation (if 0 - then the server does not listen to the port, 1 - listens).
The signals in this case solve the problem with listening to the port, i.e. slot newuser () is currently called only when a new connection to the server appears.
tcpServer = new QTcpServer(this); connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newuser())); if (!tcpServer->listen(QHostAddress::Any, 33333) && server_status==0) { qDebug() << QObject::tr("Unable to start the server: %1.").arg(tcpServer->errorString()); } else { server_status=1; qDebug() << QString::fromUtf8(" !"); } 


Connecting multiple clients to the server in parallel

The code below demonstrates how to create a new socket and make it listen to signals. We also get a socket descriptor in it, which we use as a key to store the socket object, which will be useful to us in our further work.
  if(server_status==1){ qDebug() << QString::fromUtf8("   !"); QTcpSocket* clientSocket=tcpServer->nextPendingConnection(); int idusersocs=clientSocket->socketDescriptor(); SClients[idusersocs]=clientSocket; connect(SClients[idusersocs],SIGNAL(readyRead()),this, SLOT(slotReadClient())); } 


QMap <int, QTcpSocket *> SClients; This map stores the objects of the created sockets. I use it, for example, if I forcibly stop the server and I need to close open sockets. If they are not closed, the client will wait a long time for a response from our server and not close the connection. Below is a version of the forced closure of all sockets.
  if(server_status==1){ foreach(int i,SClients.keys()){ QTextStream os(SClients[i]); os.setAutoDetectUnicode(true); os << QDateTime::currentDateTime().toString() << "\n"; SClients[i]->close(); SClients.remove(i); } tcpServer->close(); qDebug() << QString::fromUtf8(" !"); server_status=0; } 


When you create a new socket, you probably already noticed the readyRead () signal, it is executed when the client sends some data to our server, at this moment we will give an answer to our client, after receiving the data.

  //   ,     QTcpSocket* clientSocket = (QTcpSocket*)sender(); //  ,  ,          int idusersocs=clientSocket->socketDescriptor(); //     QTextStream os(clientSocket); os.setAutoDetectUnicode(true); os << "HTTP/1.0 200 Ok\r\n" "Content-Type: text/html; charset=\"utf-8\"\r\n" "\r\n" "<h1>Nothing to see here</h1>\n" << QDateTime::currentDateTime().toString() << "\n"; //       qDebug, //      GET       . qDebug() << clientSocket->readAll()+"\n\r"); //     clientSocket->close(); //      SClients.remove(idusersocs); 


Thus, we get a server (for example HTTP), which listens to port 33333, will be able to process several requests simultaneously and give the desired result.

image

PS In the future I will write about transferring a large amount of data using sockets.

Source: https://habr.com/ru/post/131472/


All Articles