シンプルなQt / C ++サーバー

最近、非常に頻繁に特定のポートをリッスンし、クライアントからデータを受信し、対応する応答を送信する必要があります。 このようなサーバーを作成し、提起されたいくつかの質問を解決する方法を初心者と共有することにしました。

この記事では、次のことを検討します。

-TCPサーバーの作成。

-複数のクライアントをサーバーに並列に接続します。

-クライアントの無効化(ソケットの無効化)。

-データの送受信。



ソース: https : //github.com/valualit/QTcpServer01



画像





QTcpServerまたは目的のポートをリッスンします


server_status変数にQTcpServerのステータス保存し、サーバー操作中に過剰が発生しないようにします(0の場合、サーバーはポートをリッスンせず、1-リッスンします)。

この場合の信号は、ポートをリッスンする問題をもう一度解決します。 現在、newuser()スロットは、サーバーへの新しい接続が表示されたときにのみ呼び出されます。

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(" !"); }
      
      







複数のクライアントをサーバーに並列接続する


以下のコードは、新しいソケットを作成し、シグナルをリッスンする方法を示しています。 また、ソケット記述子を取得します。これは、ソケットオブジェクトを保存するためのキーとして使用します。これは、今後の作業で役立ちます。

  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; このマップは、作成されたソケットのオブジェクトを保存します。 たとえば、サーバーを強制的に停止し、開いているソケットを閉じる必要がある場合に使用します。 それらが閉じられていない場合、クライアントはサーバーからの応答を長時間待機し、接続を閉じません。 以下は、すべてのソケットを強制的に閉じるオプションです。

  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; }
      
      







新しいソケットを作成するとき、おそらくreadyRead()シグナルに既に気づいているでしょう。クライアントがサーバーにデータを送信すると実行されます。この時点で、データを受信した後、クライアントに回答します。



  //   ,     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);
      
      







したがって、ポート33333でリッスンするサーバー(HTTPなど)を取得し、複数の要求を一度に処理して、目的の結果を得ることができます。



画像



PS将来的には、ソケットを使用した大量のデータの転送について書きます。



All Articles