Qt
Réseau Qt
Recherche…
Introduction
Qt Network fournit des outils pour utiliser facilement de nombreux protocoles réseau dans votre application.
Client TCP
Pour créer une connexion TCP dans Qt, nous utiliserons QTcpSocket . Tout d'abord, nous devons nous connecter avec connectToHost
.
Par exemple, pour vous connecter à un serveur tcp local: _socket.connectToHost(QHostAddress("127.0.0.1"), 4242);
Ensuite, si nous avons besoin de lire les données du serveur, nous devons connecter le signal readyRead à un emplacement. Comme ça:
connect(&_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
et enfin, on peut lire les données comme ça:
void MainWindow::onReadyRead()
{
QByteArray datas = _socket.readAll();
qDebug() << datas;
}
Pour écrire des données, vous pouvez utiliser la méthode write(QByteArray)
:
_socket.write(QByteArray("ok !\n"));
Ainsi, un client TCP de base peut ressembler à ceci:
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpSocket>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void onReadyRead();
private:
Ui::MainWindow *ui;
QTcpSocket _socket;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QHostAddress>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_socket(this)
{
ui->setupUi(this);
_socket.connectToHost(QHostAddress("127.0.0.1"), 4242);
connect(&_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onReadyRead()
{
QByteArray datas = _socket.readAll();
qDebug() << datas;
_socket.write(QByteArray("ok !\n"));
}
mainwindow.ui: (vide ici)
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>25</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
Serveur TCP
Créer un serveur TCP dans Qt est également très simple, en effet, la classe QTcpServer fournit déjà tout ce dont nous avons besoin pour faire le serveur.
Tout d'abord, nous devons écouter n'importe quelle adresse IP, un port aléatoire et faire quelque chose lorsqu'un client est connecté. comme ça:
_server.listen(QHostAddress::Any, 4242);
connect(&_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
Ensuite, quand il y a une nouvelle connexion, nous pouvons l'ajouter à la liste des clients et nous préparer à lire / écrire sur le socket. Comme ça:
QTcpSocket *clientSocket = _server.nextPendingConnection();
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
_sockets.push_back(clientSocket);
Le stateChanged(QAbstractSocket::SocketState)
nous permet de supprimer le socket dans notre liste lorsque le client est déconnecté.
Donc, voici un serveur de chat de base:
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void onNewConnection();
void onSocketStateChanged(QAbstractSocket::SocketState socketState);
void onReadyRead();
private:
Ui::MainWindow *ui;
QTcpServer _server;
QList<QTcpSocket*> _sockets;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QHostAddress>
#include <QAbstractSocket>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_server(this)
{
ui->setupUi(this);
_server.listen(QHostAddress::Any, 4242);
connect(&_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onNewConnection()
{
QTcpSocket *clientSocket = _server.nextPendingConnection();
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
_sockets.push_back(clientSocket);
for (QTcpSocket* socket : _sockets) {
socket->write(QByteArray::fromStdString(clientSocket->peerAddress().toString().toStdString() + " connected to server !\n"));
}
}
void MainWindow::onSocketStateChanged(QAbstractSocket::SocketState socketState)
{
if (socketState == QAbstractSocket::UnconnectedState)
{
QTcpSocket* sender = static_cast<QTcpSocket*>(QObject::sender());
_sockets.removeOne(sender);
}
}
void MainWindow::onReadyRead()
{
QTcpSocket* sender = static_cast<QTcpSocket*>(QObject::sender());
QByteArray datas = sender->readAll();
for (QTcpSocket* socket : _sockets) {
if (socket != sender)
socket->write(QByteArray::fromStdString(sender->peerAddress().toString().toStdString() + ": " + datas.toStdString()));
}
}
(utilisez le même mainwindow.ui que l'exemple précédent)