Qt 网络编程

QT 网络编程

TCP 编程

模块引入

QT += network

在这里插入图片描述

头文件

#include <QTcpServer> // TCP服务器端使用
#include <QTcpSocket> // TCP服务器和客户端都使用

编程流程

服务端

1)实例化 QTcpServer 对象 -----------------------------> socket
2)进入监听状态 ----> listen(QTcpServer类) // 不需要再绑定了----------->bind + listen
3)监测客户端连接 ---- newConnection 信号(QTcpServer类)
----------------> 有新连接过来,server 就能收到 newConnection 信号
4)QTcpSocket *client <---- 获得连接 ---- nextPendingConnection(QTcpServer类) ---->accept
5)连接对端接收信号 ------ readyRead(QTcpSocket类)
---------------------->如果对端有数据发送,server 就能收到 readyRead 信号
6)读取客户端消息 ------ readAll(QTcpSocket类) --------------------------> recv:读取数据
7)发送数据 ------ write(QTcpSocket类) ----> send:发数据
8)关闭连接 ------ disconnectFromHost() -------------------> close
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

客户端

1)实例化 QTcpSocket 对象;
2)连接服务器 ------ connectToHost ------> 接下来使用 waitForConnected 来判断是否连接成功
3)连接对端接收信号 ------ readyRead 信号
4)发送数据 ------ write()
5)关闭连接 ------ disconnectFromHost()
在这里插入图片描述
在这里插入图片描述

💡 客户端实现

widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QtWidgets>
#include <QTcpSocket>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();private slots:void on_connectBtn_clicked();void recvSlot();void on_sendBtn_clicked();
//    void whetherConnectedSlot();		// 判断是否连接成功,方法二private:Ui::Widget *ui;QTcpSocket *client;bool flag;
};#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);this->setWindowTitle("客户端");client = new QTcpSocket(this);QObject::connect(client, SIGNAL(readyRead()), this,  SLOT(recvSlot()));// 判断是否连接成功,方法二
//    QObject::connect(client, SIGNAL(connected()), this,  SLOT(whetherConnectedSlot()));
}Widget::~Widget()
{delete ui;
}// void Widget::whetherConnectedSlot()			// 判断是否连接成功,方法二
// {
//     flag = true;
// }void Widget::on_connectBtn_clicked()
{client->connectToHost(ui->ipEdit->text(), ui->portEdit->text().toShort());// 判断是否连接成功,方法一if (!client->waitForConnected(1000))           {qDebug() << "Failed to connect. ";return ;}qDebug() << "Connected successfully! ";ui->connectBtn->setText("断开");
}void Widget::recvSlot()
{QByteArray buffer = client->readAll();ui->recvEdit->setText(QString::fromLocal8Bit(buffer));
}void Widget::on_sendBtn_clicked()
{QString buffer = ui->sendEdit->toPlainText();client->write(buffer.toLocal8Bit());
}

在这里插入图片描述

💡 服务器实现

widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QtWidgets>
#include <QTcpServer>
#include <QTcpSocket>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();private slots:void on_connectBtn_clicked();void connectSlot();void recvSlot();void on_sendBtn_clicked();private:Ui::Widget *ui;QTcpServer *server;QTcpSocket *client;
};#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);server = new QTcpServer(this);this->setWindowTitle("服务器");// 这个信号触发,代表有客户端连接QObject::connect(server, SIGNAL(newConnection()), this,  SLOT(connectSlot()));
}Widget::~Widget()
{delete ui;
}void Widget::on_connectBtn_clicked()
{// 监听是否有客户端连入,不阻塞等待if (!server->listen(QHostAddress::Any, ui->portEdit->text().toUShort())){qDebug() << "Failed to listen. ";return ;}ui->connectBtn->setText("关闭");
}void Widget::connectSlot()
{// 接受新的客户端连接client = server->nextPendingConnection();if (client == 0){qDebug() << "There are no pending connections. ";return ;}// 一定要等到接受连接后,再去做客户端的信号连接QObject::connect(client, SIGNAL(readyRead()), this,  SLOT(recvSlot()));
}void Widget::recvSlot()
{QByteArray buffer = client->readAll();// 编码转换:对方必须按照 GBK 格式发送ui->recvEdit->setText(QString::fromLocal8Bit(buffer));
}void Widget::on_sendBtn_clicked()
{QString buffer = ui->sendEdit->toPlainText();	// 从textEdit中获取的内容一定是utf8编码client->write(buffer.toLocal8Bit());
}

在这里插入图片描述

💡 服务器与客户端交互

在这里插入图片描述

UDP 编程

模块引入

QT += network

在这里插入图片描述

头文件

#include

编程流程

1)实例化 QUdpSocket 对象 ------------------------------------------> socket
2)绑定地址、端口 ------ bind(QHostAddress::LocalHost,8888) -----> bind
3)收发报文 ------ readDatagram、writeDatagram ------------------> recvfrom/sendto
在这里插入图片描述

// 类和接口
bool 	QUdpSocket::hasPendingDatagrams() const;
qint64 	QUdpSocket::readDatagram(char * data, qint64 maxSize, QHostAddress * address = 0, quint16 * port = 0);
qint64 	QUdpSocket::writeDatagram(const char * data, qint64 size, const QHostAddress & address, quint16 port);

实现一个聊天功能,使用 UDP 通信。首先通过一个登录界面,输入服务器的 IP 和端口,点击登录后,将 IP 和端口传到聊天界面,然后通过 UDP 进行聊天(服务器)。

💡 服务器实现

在这里插入图片描述

chatpage.h
#ifndef CHATPAGE_H
#define CHATPAGE_H#include <QtWidgets>
#include <QUdpSocket>
#include "globalvalue.h"namespace Ui {
class ChatPage;
}class ChatPage : public QWidget
{Q_OBJECTpublic:explicit ChatPage(QWidget *parent = 0);~ChatPage();private:Ui::ChatPage *ui;QUdpSocket *socket;QHostAddress sender;        // 定义对端的地址,以便后续发送使用quint16 senderPort;private slots:void readPendingDatagrams();void on_sendBtn_clicked();
};#endif // CHATPAGE_H
chatpage.cpp
#include "chatpage.h"
#include "ui_chatpage.h"ChatPage::ChatPage(QWidget *parent) :QWidget(parent),ui(new Ui::ChatPage)
{ui->setupUi(this);this->setWindowTitle("聊天");// 初始化一个 QUdpSocket 对象socket = new QUdpSocket(this);// 绑定服务器的地址和IP,客户端省略此句socket->bind(QHostAddress(GlobalValue::ipaddr), GlobalValue::port);connect(socket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
}ChatPage::~ChatPage()
{delete ui;
}void ChatPage::readPendingDatagrams()
{// 如果udp缓冲区有报文数据的话while (socket->hasPendingDatagrams()){QByteArray datagram;    // 初始化一个字节流缓冲区datagram.resize(socket->pendingDatagramSize());		// 重设缓冲区的大小socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);// 对方发送的字节流必须是GBK编码ui->recvEdit->setText(QString::fromLocal8Bit(datagram));}
}
void ChatPage::on_sendBtn_clicked()
{// 如果已经接收过消息,那么sender和senderPort已经有对方的地址了socket->writeDatagram(ui->sendEdit->toPlainText().toLocal8Bit(), sender, senderPort);
}

在这里插入图片描述

globalvalue.h
#ifndef GLOBALVALUE_H
#define GLOBALVALUE_H#include <QString>class GlobalValue           // 此类仅用于存放静态变量
{
public:GlobalValue();static QString ipaddr;static quint16 port;
};#endif // GLOBALVALUE_H
globalvalue.cpp
#include "globalvalue.h"QString GlobalValue::ipaddr;
quint16 GlobalValue::port;GlobalValue::GlobalValue()
{
}
userver.h
#ifndef USERVER_H
#define USERVER_H#include <QtWidgets>
#include "chatpage.h"
#include "globalvalue.h"namespace Ui {
class UServer;
}class UServer : public QWidget
{Q_OBJECTpublic:explicit UServer(QWidget *parent = 0);~UServer();private slots:void on_pushButton_clicked();private:Ui::UServer *ui;ChatPage *chatting;
};#endif // USERVER_H
userver.cpp
#include "userver.h"
#include "ui_userver.h"UServer::UServer(QWidget *parent) :QWidget(parent),ui(new Ui::UServer)
{ui->setupUi(this);this->setWindowTitle("登录");
}UServer::~UServer()
{delete ui;
}void UServer::on_pushButton_clicked()
{GlobalValue::ipaddr = ui->ipEdit->text();GlobalValue::port = ui->portEdit->text().toUShort();chatting = new ChatPage;chatting->show();   // 初始化一个新的界面,然后进行跳转this->close();
}

运行效果如下:
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/297204.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为防火墙小企业简单应用命令行配置

实现&#xff1a; 1、内网访问外网 2、内网和外网访问dmz区ftp服务器 3、开启ftp的aspf功能 4、开启内网黑洞功能 防火墙配置&#xff1a; interface GigabitEthernet1/0/0 undo shutdown ip address 10.0.0.1 255.255.255.0 service-manage ping permit interface GigabitEth…

CCMCache的区别

CCM是Closely coupled memories的缩写&#xff0c;中文名称是紧耦合存储器&#xff0c;哈佛架构下&#xff0c;一般有两种CCM&#xff0c;分别是ICCM和DCCM&#xff0c; ICCM主要用来存储指令和数据&#xff0c;DCCM仅用来存储数据。一般中低端MCU上没有提供多级Cache,再加上指…

栈的常见题型

1.有效的括号 char pairs(char a) {if(a})return {;if(a])return [;if(a))return (;return 0; } bool isValid(char* s) {char* stack(char*)malloc(sizeof(char)*10000);int top0;int lenstrlen(s);if(len%21)return false;for(int i0;s[i];i){char chpairs(s[i]);if(ch){if(t…

如何在飞书自建项目中接入ChatGPT打造智能问答助手并远程访问

文章目录 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 前言 在飞书中创建chatGPT机器人并且对话&#xff0c;在下面操作步骤中…

GD32移植STM32工程(因为懒,所以移植)

文章目录 一、前言二、差异性三、软件移植部分1.前期准备1.1 安装GD32固件库1.2 选择所用芯片 2.修改程序2.1 启动时间&#xff08;内部时钟可不改&#xff09;2.2 主频2.2.1 系统时钟配置2.2.2 108MHz宏定义第一处第二处第三处第四处第五处 2.2.3 串口2.2.4 FLASH 四、总结 一…

KHBC靶场-->打不穿?笑死

最近这不是在上文件上传的课吗&#xff1f;刚好老师也布置了一堆靶场&#xff0c;刚好来挑一个显眼包 没错他就是KHBC靶场&#xff01;&#xff01;&#xff08;看他不顺眼很久了…

顶级旗舰ET9出道,蔚来还是那个「最不计成本」的中国车品牌

作者 |张祥威 编辑 |德新 2008年&#xff0c;李斌和新浪的曹国伟几人一起喝酒&#xff0c;发了第一条微博&#xff0c;「天冷带围巾&#xff0c;心冷发微博」&#xff0c;一晚上涨了2000多个粉丝&#xff0c;他偶尔还会针砭时事&#xff0c;很快积累了最早一波粉丝。 创立蔚来…

14章总结

一.lambda表达式 1.lambda表达式简介 lambda表达式不能独立执行&#xff0c;因此必须实现函数式接口&#xff0c;并且会返回一个函数式接口的对象。 语法&#xff1a; ()->结果表达式 参数->结果表达式 (参数1&#xff0c;参数2&#xff0c;...&#xff0c;参数n)->…

【leetcode100-019】【矩阵】螺旋矩阵

【题干】 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 【思路】 不难注意到&#xff0c;每进行一次转向&#xff0c;都有一行/列被输出&#xff08;并失效&#xff09;&#xff1b;既然已经失效&#xff0c;那我…

《面试专题-----经典高频面试题收集三》解锁 Java 面试的关键:深度解析并发编程基础篇高频经典面试题(第三篇)

目录 并发编程面试题1.什么是进程、线程、协程&#xff0c;他们之间的关系是怎样的2.协程对于多线程有什么优缺点吗 并发编程面试题 1.什么是进程、线程、协程&#xff0c;他们之间的关系是怎样的 进程: 本质上是⼀个独⽴执⾏的程序&#xff0c;进程是操作系统进⾏资源分配和…

鸿蒙应用开发 自定义下拉刷新动画

1 概述 属性动画&#xff0c;是最为基础的动画&#xff0c;其功能强大、使用场景多&#xff0c;应用范围较广。常用于如下场景中&#xff1a; 一、页面布局发生变化。例如添加、删除部分组件元素。二、页面元素的可见性和位置发生变化。例如显示或者隐藏部分元素&#xff0c;…

【python】python课设 天气预测数据分析及可视化(完整源码)

目录 1. 前言2. 项目结构3. 详细介绍3.1 main.py3.2 GetModel.py3.3 GetData.py3.4 ProcessData.py3.5天气网.html 4. 成果展示 1. 前言 本文介绍了天气预测数据分析及可视化的实现过程使用joblib导入模型和自定义模块GetModel获取模型&#xff0c;输出模型的MAE。使用pyechart…