Für die Arbeit mit dem TCP/IP -Stack bietet Qt die Klassen QTcpServer, QTcpSocket, und QUdpSocket. Für eine erste Bekanntschaft mit der Arbeit eines lokalen Netzwerks schreiben wir Echo Server . Die Aufgabe des Echoservers besteht darin, die von ihm empfangenen Daten wie ein Echo bei einer menschlichen Stimme an den Sender zurückzusenden. Telnet wird verwendet, um eine Verbindung zum Server herzustellen.
>
TELNET
(engl. TERMINAL NETwork) - ein Netzwerkprotokoll zur Implementierung einer Textschnittstelle über ein Netzwerk (in moderner Form - unter Verwendung des
TCP-Transports)
Der Name
"telnet"
hat auch einige Dienstprogramme, die die Clientseite des Protokolls implementieren.
>
>
Im vorgeschlagenen Programm lauscht ein Objekt der Klasse QTcpServer auf einen der Ports des TCP / IP Protokollstapels von allen Hosts im Netzwerk. Die Überwachung eines Ports wird mit der Methode listen() eingestellt, wobei die angegebene IP-Adresse oder der IP-Adressbereich und der Überwachungsport angegeben werden.
Wenn sich der Client mit dem Port verbindet, wird das newConnection () Signal aufgerufen, das mit dem Slot SlotNewConnection () verbunden wird, in diesem Slot wird die Client-Verbindung als QTcpSocket initiiert Objekt auf der Serverseite mit der Methode nextPendingConnection(), die einen Zeiger auf das QTcpSocket zurückgibt.
Zwei Steckplätze werden mit der neuen Buchse verbunden. Der erste Slot, slotServerRead () , wird mit dem readyRead-Signal vom Socket verbunden und aufgerufen, wenn der Socket Daten empfängt, die zum Lesen bereit sind. Der zweite Slot slotClientDisconnected () ist mit dem Disconnected () Signal verbunden, das aufgerufen wird, wenn der Client sich vom Server trennt und die Verbindung von der Serverseite her beenden muss.
Projektstruktur für die Arbeit mit QTcpServer
Es wird eine Konsolenanwendung erstellt, daher werden Klassen wie MainWindow in der Anwendung nicht verwendet.
- EchoServer.pro - Projektprofil;
- main.cpp - Hauptquellcodedatei;
- mytcpserver.h - Server-Header-Datei;
- mytcpserver.cpp - Quellcodedatei des Servers;
EchoServer.pro
In dieser Datei müssen Sie ein Qt -Modul hinzufügen, um mit dem Netzwerk zu arbeiten.
QT += network
main.cpp
Alles, was Sie in dieser Datei tun müssen, ist, die Server-Header-Datei aufzunehmen und eine Server-Instanz zu erstellen.
#include <QCoreApplication> #include "mytcpserver.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); MyTcpServer server; return a.exec(); }
mytcpserver.h
Diese Klasse ist ein Wrapper für die Arbeit mit QTcpServer und geerbt von QObject für die Verwendung von Signalen und Slots .
#ifndef MYTCPSERVER_H #define MYTCPSERVER_H #include <QObject> #include <QTcpServer> #include <QTcpSocket> class MyTcpServer : public QObject { Q_OBJECT public: explicit MyTcpServer(QObject *parent = 0); public slots: void slotNewConnection(); void slotServerRead(); void slotClientDisconnected(); private: QTcpServer * mTcpServer; QTcpSocket * mTcpSocket; }; #endif // MYTCPSERVER_H
mytcpserver.cpp
#include "mytcpserver.h" #include <QDebug> #include <QCoreApplication> MyTcpServer::MyTcpServer(QObject *parent) : QObject(parent) { mTcpServer = new QTcpServer(this); connect(mTcpServer, &QTcpServer::newConnection, this, &MyTcpServer::slotNewConnection); if(!mTcpServer->listen(QHostAddress::Any, 6000)){ qDebug() << "server is not started"; } else { qDebug() << "server is started"; } } void MyTcpServer::slotNewConnection() { mTcpSocket = mTcpServer->nextPendingConnection(); mTcpSocket->write("Hello, World!!! I am echo server!\r\n"); connect(mTcpSocket, &QTcpSocket::readyRead, this, &MyTcpServer::slotServerRead); connect(mTcpSocket, &QTcpSocket::disconnected, this, &MyTcpServer::slotClientDisconnected); } void MyTcpServer::slotServerRead() { while(mTcpSocket->bytesAvailable()>0) { QByteArray array = mTcpSocket->readAll(); mTcpSocket->write(array); } } void MyTcpServer::slotClientDisconnected() { mTcpSocket->close(); }
Arbeiten mit Echo Server
Nachdem Sie das Projekt erstellt und Ihre Konsolenanwendung gestartet haben, verwenden Sie eine beliebige Software, die Telnet unterstützt, zum Beispiel Putty, und stellen Sie eine Verbindung zum konfigurierten Port her. Versuchen Sie, die Daten an den Server zu senden, um sicherzustellen, dass er sie an Sie zurückgibt. In einigen Fällen kann dies nicht passieren oder Sie können überhaupt keine Verbindung herstellen, dann deaktivieren Sie FireWall , oft ist das Problem darin versteckt.
Eine Demonstration der Anwendung mit zusätzlichen Kommentaren wird im Video-Tutorial präsentiert.
Link zum Download des Projekts in einem Zip-Archiv: echoserver.zip
Добрый день, разрешите вопрос:
во всех примерах работы с QTcpServer его всегда создают в main.cpp, нет ли возможности корректно сохдать его в MainWindow.cpp ?
Просто если перенести код в MainWindow.cpp
то возникает ошибка на клиенте QNativeSocketEngine::write() was not called in QAbstractSocket::ConnectedState
Переменную myserver нужно объявить в заголовочном файле, в противном случае после выполнения конструктора окна эта переменная удаляется, поскольку создана на стеке конструктора.
спасибо, но уже не актуально. Я уже написал классы многопоточного сервера и они переносимы, раскидал их по четырем приложениям, даже не меняя код.
Hi, great post.
If I were to reimplement QTcpServer for the purposes of SSL, shouldn't incomingConnection(int socket) just be automatically called after a connection occurs?