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.mzph.cn/news/283812.shtml

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

相关文章

日利率

2019独角兽企业重金招聘Python工程师标准>>> 利率计算 转载于:https://my.oschina.net/u/3342652/blog/1649028

Kafka 安装详解

注意&#xff1a;确保有JDK1.8版本及以上 官方文档&#xff1a;https://kafka.apache.org/quickstart 清华镜像下载&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/apache/kafka/ 首先下载安装包&#xff0c;在linux及Windows都可以使用。 1. Centos 安装部署 1.1 下载 将下…

【Maui正式版】创建可跨平台的Maui程序,以及有关依赖注入、MVVM双向绑定的实现和演示...

前言&#xff1a;Maui终于在2022年8月9日推送出来了。今儿就迫不及待来把玩一下先。A、我本地已有VS2022&#xff0c;不过版本比较老&#xff0c;此处选择更新。工具 -> 获取功能和更新里面&#xff0c;可以获取到新版本更新。B、最新版本是17.3.0&#xff0c;我本地只有17.…

WebSQL存储

2019独角兽企业重金招聘Python工程师标准>>> WebSQL这种存储技术&#xff0c;相对于学过数据库的人来说&#xff0c;还是比较容易理解和上手的&#xff0c;主要就是它的存储风格和我们一般所学的SQL Server 和Oracle比较像&#xff0c;对于HTML5来说&#xff0c;当然…

抖音服务器带宽有多大,才能供上亿人同时刷?

最近看到一个有意思的提问&#xff1a;抖音服务器带宽有多大&#xff0c;为什么能够供那么多人同时刷&#xff1f;今天来给小伙伴们科普一下。 抖音&#xff0c;百度&#xff0c;阿里云&#xff0c;腾讯都是自建的数据中心&#xff0c;都是 T 级别出口带宽&#xff08;总出口带…

ASP.NET Core 5.0中的Host.CreateDefaultBuilder执行过程

通过Rider调试的方式看了下ASP.NET Core 5.0的Web API默认项目&#xff0c;重点关注Host.CreateDefaultBuilder(args)中的执行过程&#xff0c;主要包括主机配置、应用程序配置、日志配置和依赖注入配置这4个部分。由于水平和篇幅有限&#xff0c;先整体理解、建立框架&#xf…

404和302

为什么80%的码农都做不了架构师&#xff1f;>>> 404 php中用header()函数是可以为返回页面添加404的头信息的&#xff0c;从而提示浏览器该网页找不到了。 所以可以使用&#xff1a;header("HTTP/1.0 404 Not Found");或者&#xff1a;header("Stat…

oracle sqlplus使用

2019独角兽企业重金招聘Python工程师标准>>> 1、常用连接方式 sqlplus / as sysdba 无需数据库进入可用状态&#xff0c;就可用用该命令登录&#xff0c;运行startup来启动。 sqlplus username/pwdhost/service_name&#xff0c;如&#xff1a; sqlplus tiger/scott…

20款IDEA 神级插件 效率提升 30 倍,写代码必备

插件目录 1. Alibaba Java Coding Guidelines 2.GsonFormat 3.A8Translation 4.Maven Helper 5.Free Mybatis plugin 6.Grep Console 7.Lombok 8.Nyan progress bar 9.FindBugs-IDEA 10.Key Promoter X 11.JavaDoc 12.ignore 13.RainbowBrackets 14.Activate-power-mode 15.C…

【温故知新】C# Linq中 Where使用技巧

微信公众号&#xff1a;趣编程ACE关注可了解更多的.NET日常实战开发技巧&#xff0c;如需源码 后台回复 源码 即可;如果觉得对你有帮助&#xff0c;欢迎关注C# Linq中 Where使用技巧hello 大家好&#xff0c;很开心又能重新分享C#编程开发技巧了&#xff0c;之前因为工作和生活…

分布式id解决方案

文章目录 1.分布式id实现方案 1.1.uuid1.2 数据库主键自增1.3 Redis自增1.4 号段模式1.5 雪花算法&#xff08;snowflake&#xff09; 1.5.1 百度&#xff08;uid-generator&#xff09;1.5.2 美团&#xff08;Leaf&#xff09;所谓id就是能够用作唯一标识的记号。 在我们日常的…

我和大象的十年往事 - 感恩、感谢、加油、腾飞

背景 http://www.idcquan.com/Special/OSCAR2018/index.html 由中国信息通信研究院主办、中国通信标准化协会支持的"OSCAR云计算开源产业大会"于2018年3月21日&#xff0d;22日在国家会议中心举行。 非常有幸获得了“OSCAR尖峰开源人物”奖项。 奖项不敢自居&#xf…

4种分布式session解决方案

cookie和session的区别和联系 cookie是本地客户端用来存储少量数据信息的&#xff0c;保存在客户端&#xff0c;用户能够很容易的获取&#xff0c;安全性不高&#xff0c;存储的数据量小 session是服务器用来存储部分数据信息&#xff0c;保存在服务器&#xff0c;用户不容易获…

Blazor University (43)JavaScript 互操作 —— 类型安全

原文链接&#xff1a;https://blazor-university.com/javascript-interop/calling-dotnet-from-javascript/type-safety/类型安全在从 JavaScript 调用 .NET[1] 部分中&#xff0c;您可能已经注意到我们的 JavaScript 的第 6 行在将随机生成的数字传递给 .NET 之前调用了 toStr…

分享 60 个神级 VS Code 插件

文章来源&#xff1a;juejin.cn/post/6994327298740600839 本文不做任何编辑器的比较&#xff0c;只是我本人日常使用 vscode 进行开发&#xff0c;并且比较喜欢折腾 vscode &#xff0c;会到处找这一些好玩的插件&#xff0c;于是越攒越多&#xff0c;今天给大家推荐一下我收…

PHP 基础篇 - PHP 中 DES 加解密详解

2019独角兽企业重金招聘Python工程师标准>>> 一、简介 DES 是对称性加密里面常见一种&#xff0c;全称为 Data Encryption Standard&#xff0c;即数据加密标准&#xff0c;是一种使用密钥加密的块算法。密钥长度是64位(bit)&#xff0c;超过位数密钥被忽略。所谓对…

PerfView专题 (第一篇): 如何寻找热点函数

一&#xff1a;背景 准备开个系列来聊一下 PerfView 这款工具&#xff0c;熟悉我的朋友都知道我喜欢用 WinDbg&#xff0c;这东西虽然很牛&#xff0c;但也不是万能的&#xff0c;也有一些场景他解决不了或者很难解决&#xff0c;这时候借助一些其他的工具来辅助&#xff0c;是…

Centos7设置IP为固定值

1.进入到系统的IP地址保存文件所在目录 [rootlocalhost ~]# cd /etc/sysconfig/network-scripts 2.修改保存IP信息的文件 [rootlocalhost ~]# vim ifcfg-eth0 &#xff08;你机器上的名字有可能不是这个&#xff0c;但是是以ifcfg-eth开头的文件&#xff09; 保存后退出 3.重启…

为 EditorConfig 文件开启错误编译失败

前言上次&#xff0c;我们介绍了 EditorConfig 文件可以自定义代码样式规则。但是&#xff0c;当我们想设置代码样式严重性&#xff0c;比如不允许编译成功时&#xff0c;又踩了不少坑。修改无效想把 var 首选项&#xff0c;从“首选"var" 仅重构”&#xff0c;改成“…

【.NET特供-第三季】ASP.NET MVC系列:传统WebForm站点和MVC站点执行机制对照

本文以图形化的方式&#xff0c;从‘执行机制’方面对照传统WebForm站点和MVC站点。请參看下面图形&#xff1a; 一、执行机制 当我们訪问一个站点的时候&#xff0c;浏览器和server都是做了哪些动作呢&#xff1f; &#xff08;本文仅仅是提供一个简单的执行过程&#xff0c;有…