QT5实现简单的TCP通信的实现

作者:培培哥 时间:2023-11-02 21:24:48 

这段时间用到了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()信号,因此为该信号添加槽函数以读取数据

QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);

void MainWindow::socket_Read_Data()
{
   QByteArray buffer;
   //读取缓冲区数据
   buffer = socket->readAll();
}

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

socket->disconnectFromHost();

2、以下是客户端的例程

首先是mainwindow.h文件:

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

private slots:

void on_pushButton_Connect_clicked();

void on_pushButton_Send_clicked();

void socket_Read_Data();

void socket_Disconnected();

private:
   Ui::MainWindow *ui;
   QTcpSocket *socket;
};

#endif // MAINWINDOW_H

然后是mainwindow.cpp文件:

//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);

socket = new QTcpSocket();

//连接信号槽
   QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);
   QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);

ui->pushButton_Send->setEnabled(false);
   ui->lineEdit_IP->setText("127.0.0.1");
   ui->lineEdit_Port->setText("8765");

}

MainWindow::~MainWindow()
{
   delete this->socket;
   delete ui;
}

void MainWindow::on_pushButton_Connect_clicked()
{
   if(ui->pushButton_Connect->text() == tr("连接"))
   {
       QString IP;
       int port;

//获取IP地址
       IP = ui->lineEdit_IP->text();
       //获取端口号
       port = ui->lineEdit_Port->text().toInt();

//取消已有的连接
       socket->abort();
       //连接服务器
       socket->connectToHost(IP, port);

//等待连接成功
       if(!socket->waitForConnected(30000))
       {
           qDebug() << "Connection failed!";
           return;
       }
       qDebug() << "Connect successfully!";

//发送按键使能
       ui->pushButton_Send->setEnabled(true);
       //修改按键文字
       ui->pushButton_Connect->setText("断开连接");
   }
   else
   {
       //断开连接
       socket->disconnectFromHost();
       //修改按键文字
       ui->pushButton_Connect->setText("连接");
       ui->pushButton_Send->setEnabled(false);
   }
}

void MainWindow::on_pushButton_Send_clicked()
{
   qDebug() << "Send: " << ui->textEdit_Send->toPlainText();
    //获取文本框内容并以ASCII码形式发送
   socket->write(ui->textEdit_Send->toPlainText().toLatin1());
   socket->flush();
}

void MainWindow::socket_Read_Data()
{
   QByteArray buffer;
   //读取缓冲区数据
   buffer = socket->readAll();
   if(!buffer.isEmpty())
   {
       QString str = ui->textEdit_Recv->toPlainText();
       str+=tr(buffer);
       //刷新显示
       ui->textEdit_Recv->setText(str);
   }
}

void MainWindow::socket_Disconnected()
{
   //发送按键失能
   ui->pushButton_Send->setEnabled(false);
   //修改按键文字
   ui->pushButton_Connect->setText("连接");
   qDebug() << "Disconnected!";
}

最后是ui的设计:

QT5实现简单的TCP通信的实现

二、服务器

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

(1)创建QTcpSever对象

server = new QTcpServer();

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

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

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

connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);

void MainWindow::server_New_Connect()
{
   //获取客户端连接
   socket = server->nextPendingConnection();
}

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

socket->write(data);

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

QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);

void MainWindow::socket_Read_Data()
{
   QByteArray buffer;
   //读取缓冲区数据
   buffer = socket->readAll();
}

(6)取消侦听

server->close();

2、以下是服务器的例程

首先是mainwindow.h文件:

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

private slots:
   void on_pushButton_Listen_clicked();

void on_pushButton_Send_clicked();

void server_New_Connect();

void socket_Read_Data();

void socket_Disconnected();

private:
   Ui::MainWindow *ui;
   QTcpServer* server;
   QTcpSocket* socket;
};

#endif // MAINWINDOW_H

然后是mainwindow.cpp文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
   QMainWindow(parent),
   ui(new Ui::MainWindow)
{
   ui->setupUi(this);

ui->lineEdit_Port->setText("8765");
   ui->pushButton_Send->setEnabled(false);

server = new QTcpServer();

//连接信号槽
   connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);
}

MainWindow::~MainWindow()
{
   server->close();
   server->deleteLater();
   delete ui;
}

void MainWindow::on_pushButton_Listen_clicked()
{
   if(ui->pushButton_Listen->text() == tr("侦听"))
   {
       //从输入框获取端口号
       int port = ui->lineEdit_Port->text().toInt();

//监听指定的端口
       if(!server->listen(QHostAddress::Any, port))
       {
           //若出错,则输出错误信息
           qDebug()<<server->errorString();
           return;
       }
       //修改按键文字
       ui->pushButton_Listen->setText("取消侦听");
       qDebug()<< "Listen succeessfully!";
   }
   else
   {
/*
       //如果正在连接(点击侦听后立即取消侦听,若socket没有指定对象会有异常,应修正——2017.9.30)
       if(socket->state() == QAbstractSocket::ConnectedState)
       {
           //关闭连接
           socket->disconnectFromHost();
       }
*/
       socket->abort();
       //取消侦听
       server->close();
       //修改按键文字
       ui->pushButton_Listen->setText("侦听");
       //发送按键失能
       ui->pushButton_Send->setEnabled(false);
   }

}

void MainWindow::on_pushButton_Send_clicked()
{
   qDebug() << "Send: " << ui->textEdit_Send->toPlainText();
   //获取文本框内容并以ASCII码形式发送
   socket->write(ui->textEdit_Send->toPlainText().toLatin1());
   socket->flush();
}

void MainWindow::server_New_Connect()
{
   //获取客户端连接
   socket = server->nextPendingConnection();
   //连接QTcpSocket的信号槽,以读取新数据
   QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);
   QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);
   //发送按键使能
   ui->pushButton_Send->setEnabled(true);

qDebug() << "A Client connect!";
}

void MainWindow::socket_Read_Data()
{
   QByteArray buffer;
   //读取缓冲区数据
   buffer = socket->readAll();
   if(!buffer.isEmpty())
   {
       QString str = ui->textEdit_Recv->toPlainText();
       str+=tr(buffer);
       //刷新显示
       ui->textEdit_Recv->setText(str);
   }
}

void MainWindow::socket_Disconnected()
{
   //发送按键失能
   ui->pushButton_Send->setEnabled(false);
   qDebug() << "Disconnected!";
}

最后是ui的设计:

QT5实现简单的TCP通信的实现

三、运行结果

QT5实现简单的TCP通信的实现

附上两个工程的下载链接:tcp_QT_jb51.rar

来源:https://blog.csdn.net/u014695839/article/details/70041771

标签:QT,TCP,通信
0
投稿

猜你喜欢

  • android 修改launcher行数和列数的方法

    2021-10-02 14:19:37
  • java实现订餐系统

    2023-08-12 04:39:06
  • Spring IOC创建对象的两种方式

    2023-09-10 15:58:27
  • C#控制台实现飞行棋游戏

    2022-03-12 04:18:40
  • Java数据结构及算法实例:三角数字

    2023-08-24 17:52:25
  • 线程阻塞唤醒工具 LockSupport使用详解

    2023-11-29 17:16:10
  • Java mongodb连接配置实践

    2022-05-02 11:50:56
  • C#类的创建与初始化实例解析

    2023-08-05 17:55:31
  • Android绘制验证码的实例代码

    2023-10-30 13:57:15
  • Android实现环形进度条的实例

    2023-01-11 17:39:22
  • Java面向对象之猜拳游戏

    2022-10-29 21:26:45
  • Jackson反序列化@JsonFormat 不生效的解决方案

    2023-06-15 20:25:37
  • java web服务器实现跨域访问

    2023-09-17 06:55:08
  • C#使用async和await实现异步编程

    2023-08-23 18:32:52
  • Android HorizontalScrollView滑动与ViewPager切换案例详解

    2023-06-05 00:48:27
  • Java 多线程学习详细总结

    2023-11-18 22:55:24
  • java二叉树面试题详解

    2021-06-13 08:40:23
  • Java源码解析之接口List

    2022-06-13 08:46:44
  • Java设计模式之模板方法模式详解

    2021-08-04 04:32:51
  • Android基于API的Tabs3实现仿优酷tabhost效果实例

    2021-07-31 18:51:02
  • asp之家 软件编程 m.aspxhome.com