zl程序教程

您现在的位置是:首页 >  工具

当前栏目

Qt 实现简单的TCP通信

QtTCP通信 实现 简单
2023-09-14 09:05:11 时间

Qt 实现简单的TCP通信

这段时间用到了QT的TCP通信,做了初步的学习与尝试,编写了一个客户端和服务器基于窗口通信的小例程。

使用QT的网络套接字需要.pro文件中加入一句:

QT += network

一、客户端

1、客户端的代码比服务器稍简单,总的来说,使用QT中的QTcpSocket类与服务器进行通信只需要以下5步:

(1)创建QTcpSocket套接字对象

socket = new QTcpSocket();

(2)使用这个对象连接服务器

socket->connectToHost(IP, port);

(3)使用write函数向服务器发送数据

socket->write(data);

(4)当socket接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据

1 QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);
2  
3 void MainWindow::socket_Read_Data()
4 {
5     QByteArray buffer;
6     //读取缓冲区数据
7     buffer = socket->readAll();
8 }

(5)断开与服务器的连接(关于close()和disconnectFromHost()的区别,可以按F1看帮助)

socket->disconnectFromHost();

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

2、以下是客户端的例程

首先是mainwindow.h文件:

 1 //mainwindow.h
 2 #ifndef MAINWINDOW_H
 3 #define MAINWINDOW_H
 4  
 5 #include <QMainWindow>
 6 #include <QTcpSocket>
 7  
 8 namespace Ui {
 9 class MainWindow;
10 }
11  
12 class MainWindow : public QMainWindow
13 {
14     Q_OBJECT
15  
16 public:
17     explicit MainWindow(QWidget *parent = 0);
18     ~MainWindow();
19  
20 private slots:
21  
22     void on_pushButton_Connect_clicked();
23  
24     void on_pushButton_Send_clicked();
25  
26     void socket_Read_Data();
27  
28     void socket_Disconnected();
29  
30 private:
31     Ui::MainWindow *ui;
32     QTcpSocket *socket;
33 };
34  
35 #endif // MAINWINDOW_H

然后是mainwindow.cpp文件:

 1 //mainwindow.cpp
 2 #include "mainwindow.h"
 3 #include "ui_mainwindow.h"
 4  
 5 MainWindow::MainWindow(QWidget *parent) :
 6     QMainWindow(parent),
 7     ui(new Ui::MainWindow)
 8 {
 9     ui->setupUi(this);
10  
11     socket = new QTcpSocket();
12  
13     //连接信号槽
14     QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);
15     QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);
16  
17     ui->pushButton_Send->setEnabled(false);
18     ui->lineEdit_IP->setText("127.0.0.1");
19     ui->lineEdit_Port->setText("8765");
20  
21 }
22  
23 MainWindow::~MainWindow()
24 {
25     delete this->socket;
26     delete ui;
27 }
28  
29 void MainWindow::on_pushButton_Connect_clicked()
30 {
31     if(ui->pushButton_Connect->text() == tr("连接"))
32     {
33         QString IP;
34         int port;
35  
36         //获取IP地址
37         IP = ui->lineEdit_IP->text();
38         //获取端口号
39         port = ui->lineEdit_Port->text().toInt();
40  
41         //取消已有的连接
42         socket->abort();
43         //连接服务器
44         socket->connectToHost(IP, port);
45  
46         //等待连接成功
47         if(!socket->waitForConnected(30000))
48         {
49             qDebug() << "Connection failed!";
50             return;
51         }
52         qDebug() << "Connect successfully!";
53  
54         //发送按键使能
55         ui->pushButton_Send->setEnabled(true);
56         //修改按键文字
57         ui->pushButton_Connect->setText("断开连接");
58     }
59     else
60     {
61         //断开连接
62         socket->disconnectFromHost();
63         //修改按键文字
64         ui->pushButton_Connect->setText("连接");
65         ui->pushButton_Send->setEnabled(false);
66     }
67 }
68  
69 void MainWindow::on_pushButton_Send_clicked()
70 {
71     qDebug() << "Send: " << ui->textEdit_Send->toPlainText();
72      //获取文本框内容并以ASCII码形式发送
73     socket->write(ui->textEdit_Send->toPlainText().toLatin1());
74     socket->flush();
75 }
76  
77 void MainWindow::socket_Read_Data()
78 {
79     QByteArray buffer;
80     //读取缓冲区数据
81     buffer = socket->readAll();
82     if(!buffer.isEmpty())
83     {
84         QString str = ui->textEdit_Recv->toPlainText();
85         str+=tr(buffer);
86         //刷新显示
87         ui->textEdit_Recv->setText(str);
88     }
89 }
90  
91 void MainWindow::socket_Disconnected()
92 {
93     //发送按键失能
94     ui->pushButton_Send->setEnabled(false);
95     //修改按键文字
96     ui->pushButton_Connect->setText("连接");
97     qDebug() << "Disconnected!";
98 }

最后是ui的设计:

 

二、服务器

1、服务器除了使用到了QTcpSocket类,还需要用到QTcpSever类。即便如此,也只是比客户端复杂一点点,用到了6个步骤:

(1)创建QTcpSever对象

server = new QTcpServer();

(2)侦听一个端口,使得客户端可以使用这个端口访问服务器

server->listen(QHostAddress::Any, port);

(3)当服务器被客户端访问时,会发出newConnection()信号,因此为该信号添加槽函数,并用一个QTcpSocket对象接受客户端访问

1 connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);
2  
3 void MainWindow::server_New_Connect()
4 {
5     //获取客户端连接
6     socket = server->nextPendingConnection();
7 }

(4)使用socket的write函数向客户端发送数据

socket->write(data);

(5)当socket接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据

1 QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);
2  
3 void MainWindow::socket_Read_Data()
4 {
5     QByteArray buffer;
6     //读取缓冲区数据
7     buffer = socket->readAll();
8 }

(6)取消侦听

server->close();

2、以下是服务器的例程

首先是mainwindow.h文件:

 1 //mainwindow.h
 2 #ifndef MAINWINDOW_H
 3 #define MAINWINDOW_H
 4  
 5 #include <QMainWindow>
 6 #include <QTcpServer>
 7 #include <QTcpSocket>
 8  
 9 namespace Ui {
10 class MainWindow;
11 }
12  
13 class MainWindow : public QMainWindow
14 {
15     Q_OBJECT
16  
17 public:
18     explicit MainWindow(QWidget *parent = 0);
19     ~MainWindow();
20  
21 private slots:
22     void on_pushButton_Listen_clicked();
23  
24     void on_pushButton_Send_clicked();
25  
26     void server_New_Connect();
27  
28     void socket_Read_Data();
29  
30     void socket_Disconnected();
31  
32 private:
33     Ui::MainWindow *ui;
34     QTcpServer* server;
35     QTcpSocket* socket;
36 };
37  
38 #endif // MAINWINDOW_H

然后是mainwindow.cpp文件:

  1 #include "mainwindow.h"
  2 #include "ui_mainwindow.h"
  3  
  4 MainWindow::MainWindow(QWidget *parent) :
  5     QMainWindow(parent),
  6     ui(new Ui::MainWindow)
  7 {
  8     ui->setupUi(this);
  9  
 10     ui->lineEdit_Port->setText("8765");
 11     ui->pushButton_Send->setEnabled(false);
 12  
 13     server = new QTcpServer();
 14  
 15     //连接信号槽
 16     connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);
 17 }
 18  
 19 MainWindow::~MainWindow()
 20 {
 21     server->close();
 22     server->deleteLater();
 23     delete ui;
 24 }
 25  
 26 void MainWindow::on_pushButton_Listen_clicked()
 27 {
 28     if(ui->pushButton_Listen->text() == tr("侦听"))
 29     {
 30         //从输入框获取端口号
 31         int port = ui->lineEdit_Port->text().toInt();
 32  
 33         //监听指定的端口
 34         if(!server->listen(QHostAddress::Any, port))
 35         {
 36             //若出错,则输出错误信息
 37             qDebug()<<server->errorString();
 38             return;
 39         }
 40         //修改按键文字
 41         ui->pushButton_Listen->setText("取消侦听");
 42         qDebug()<< "Listen succeessfully!";
 43     }
 44     else
 45     {
 46 /*
 47         //如果正在连接(点击侦听后立即取消侦听,若socket没有指定对象会有异常,应修正——2017.9.30)
 48         if(socket->state() == QAbstractSocket::ConnectedState)
 49         {
 50             //关闭连接
 51             socket->disconnectFromHost();
 52         }
 53 */
 54         socket->abort();
 55         //取消侦听
 56         server->close();
 57         //修改按键文字
 58         ui->pushButton_Listen->setText("侦听");
 59         //发送按键失能
 60         ui->pushButton_Send->setEnabled(false);
 61     }
 62  
 63 }
 64  
 65 void MainWindow::on_pushButton_Send_clicked()
 66 {
 67     qDebug() << "Send: " << ui->textEdit_Send->toPlainText();
 68     //获取文本框内容并以ASCII码形式发送
 69     socket->write(ui->textEdit_Send->toPlainText().toLatin1());
 70     socket->flush();
 71 }
 72  
 73 void MainWindow::server_New_Connect()
 74 {
 75     //获取客户端连接
 76     socket = server->nextPendingConnection();
 77     //连接QTcpSocket的信号槽,以读取新数据
 78     QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);
 79     QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);
 80     //发送按键使能
 81     ui->pushButton_Send->setEnabled(true);
 82  
 83     qDebug() << "A Client connect!";
 84 }
 85  
 86 void MainWindow::socket_Read_Data()
 87 {
 88     QByteArray buffer;
 89     //读取缓冲区数据
 90     buffer = socket->readAll();
 91     if(!buffer.isEmpty())
 92     {
 93         QString str = ui->textEdit_Recv->toPlainText();
 94         str+=tr(buffer);
 95         //刷新显示
 96         ui->textEdit_Recv->setText(str);
 97     }
 98 }
 99  
100 void MainWindow::socket_Disconnected()
101 {
102     //发送按键失能
103     ui->pushButton_Send->setEnabled(false);
104     qDebug() << "Disconnected!";
105 }

最后是ui的设计:

 

三、运行结果

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓