(9)Qt---网络编程

news2024/12/29 12:20:24

目录

1. 复习

1.1 UDP 与TCP

1.2 IP地址与端口号

2. 前期准备

3. 编程内容


1. 复习

1.1 UDP 与TCP

UDP TCP 协议相同点:都存在于传输层

  • TCP(即传输控制协议):

是一种面向连接的传输层协议,它能提供高可靠性通信(即数据无误、数据无丢失、

数据无失序、数据无重复到达的通信)

适用情况:

 1、适合于对传输质量要求较高,以及传输大量数据的通信。

 2、在需要可靠数据传输的场合,通常使用TCP协议

 3、MSN/QQ等即时通讯软件的用户登录账户管理相关的功能通常采用TCP协议

  • UDP :用户数据报协议

UDP(User Datagram Protocol)用户数据报协议,是不可靠的无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。

适用情况:

1、发送小尺寸数据(如对DNS服务器进行IP地址查询时)

2、在接收到数据,给出应答较困难的网络中使用UDP。

3、适合于广播/组播式通信中。

4、MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议

5、流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输

1.2 IP地址与端口号

  • IP地址

基本概念:

IP地址是Internet中主机的标识,Internet中的主机要与别的机器通信必须具有一个IP地址。

  • 端口号

基本概念:

为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号来区分。

众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由UNIX系统占用)

已登记端口:1024~49151    

动态或私有端口:49152~65535

自定义程序的端口号建议:2000-65535,去除连号,例如8888

2. 前期准备

跟数据库一样,网络功能也需要在.pro文件中增加network模块。

Qt的TCP通信结构图,如下所示(原理大概下图所示,但是具体的API有所不同)。

3. 编程内容

本次要实现一个基于TCP的聊天程序,需要使用的类有:

  • QTcpServer

服务器管理类:管理服务器的多个连接,直接继承了QObject,因此不具备IO能力。

相关函数如下:

// 构造函数
QTcpServer::QTcpServer(QObject * parent = 0)
// 服务器开启监听,等待客户主动发起连接
// 参数1:监听来自于哪个IP地址的请求,默认值为不限制IP地址,QHostAddress类是IP地址的封装类。
// 参数2:服务器端口号
// 返回值:监听开启结果
bool QTcpServer::listen(
                const QHostAddress & address = QHostAddress::Any, 
                quint16 port = 0)
// 有新连接建立的通知信号
void QTcpServer::newConnection() [signal]
// 服务器是否还在监听
bool QTcpServer::isListening() const
// 关闭服务器
void QTcpServer::close()
// 返回一个就绪的连接对象,此对象用于跟某个客户端进行IO操作
QTcpSocket * QTcpServer::nextPendingConnection() [virtual]
  • QTcpSocket

TCP连接类:进行网络IO操作,间接继承QIODevice类。

相关函数如下:

// 构造函数
QTcpSocket::QTcpSocket(QObject * parent = 0)
// 连接到服务器
// 参数1:服务器的IP地址
// 参数2:服务器的端口号
// 参数3:读写模式,默认为可读可写
void QAbstractSocket::connectToHost(const QString & hostName,
                                    quint16 port, 
                                    OpenMode openMode = ReadWrite) [virtual]
// 连接是否处于打开状态
bool QIODevice::isOpen() const
// 关闭连接
void QIODevice::close() [virtual]
// 拿到对面的IP地址封装类对象,如果没有连接返回QHostAddress::Null
QHostAddress QAbstractSocket::peerAddress() const
// 连接断开发射的信号
void QAbstractSocket::disconnected() [signal]
// 有数据可读时发射的信号
void QIODevice::readyRead() [signal]
  • QTextStream 

文本流类:是一种高效地文本数据IO的辅助类。

// 构造函数
// 参数为QIODevice的派生类对象
QTextStream::QTextStream(QIODevice * device)
// 发送字符串
// 参数必须是QString类型,注意不要使用const char*
// 返回值是当前类型的引用,表示支持链式调用,因此连续追加发送的内容
QTextStream & QTextStream::operator<<(const QString & string)
// 读取最大值为maxlen个字符的内容到返回值
QString QTextStream::read(qint64 maxlen)
// 读取最大字符数maxlen的一行字符到返回值
QString QTextStream::readLine(qint64 maxlen = 0)
// 读取所有字符到返回值
// 
QString QTextStream::readAll()

client:

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QtWidgets>
//连接类
#include <QTcpSocket>
//文件流类
#include <QTextStream>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;
    QTcpSocket *client; //连接对象

private slots:
    void btnConnClickedSlot();
    void btnSendClickedSlot();
    //连接和断开的检测槽函数
    void connectedSlot();
    void diaconnectedSlot();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

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

    connect(ui->pushButtonConn,SIGNAL(clicked()),this,SLOT(btnConnClickedSlot()));
    connect(ui->pushButtonSend,SIGNAL(clicked()),this,SLOT(btnSendClickedSlot()));

    //设置窗口标记为顶层
    setWindowFlags(Qt::WindowStaysOnTopHint);

    // 创建连接对象
    client = new QTcpSocket(this);
    //连接状态检测的信号槽
    connect(client,SIGNAL(connected()),this,SLOT(connectedSlot()));
    connect(client,SIGNAL(disconnected()),this,SLOT(diaconnectedSlot()));

}

Dialog::~Dialog()
{
    // 如果客户端还在连着,关掉
    if(client->isOpen()){
        client->close();
    }
    delete ui;
}
void Dialog::btnConnClickedSlot(){
    //默认输入有效,连接到服务器
    //参数1:服务器的IP地址
    //参数2:服务器的端口号
    client->connectToHost(ui->lineEditIp->text(),8887);

}

void Dialog::btnSendClickedSlot(){
    //获取用户输入的内容
     QString msg = ui->lineEditMsg->text();
     if(msg == ""){
         QMessageBox::warning(this,"提示","请输入要发送的内容!");
         return;
     }
     //创建文本流对象
     QTextStream output(client);
     //发送内容
     output << msg;
     //清空输入框
     ui->lineEditMsg->clear();
}

void Dialog::connectedSlot()
{
    //屏蔽连接按钮
    ui->pushButtonConn->setEnabled(false);
    ui->pushButtonConn->setText("已连接");
    //释放发送按钮
    ui->pushButtonSend->setEnabled(true);
}

void Dialog::diaconnectedSlot()
{
    //恢复连接按钮
    ui->pushButtonConn->setEnabled(true);
    ui->pushButtonConn->setText("连接!");
    //屏蔽发送按钮
    ui->pushButtonSend->setEnabled(false);
}

ui界面

 server:

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
//网络相关类
#include <QTcpServer>
#include <QTcpSocket>
#include <QDateTime>
#include <QTextStream>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;
    // 管理类服务器对象
    QTcpServer *server;
    QTcpSocket*socket = NULL; //简单期间,只保留一个客户端连接

private slots:
    //新连接建立的槽函数
    void newConnSlot();
    //网络连接断开的槽函数
    void disconnectedSlot();
    //读取信息的槽函数
    void readReadSlot();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    // 设置窗口标记,始终前台显示
    setWindowFlags(Qt::WindowStaysOnTopHint);
    // 创建管理类对象
    server = new QTcpServer(this);
    //连接服务器通知的信号槽
    connect(server,SIGNAL(newConnection()),this,SLOT(newConnSlot()));
    // 开启监听,等待客户主动发起连接
    //参数1:监听来自哪个IP地址的请求,默认值为不限制IP地址
    //QHostAddress类是ip地址的封装类
    //参数2:服务器端口号
    server->listen(QHostAddress::Any,8887);

}

Dialog::~Dialog()
{
    if(server->isListening()) // 如果在监听
            // 关闭服务器
            server->close();
    delete ui;
}


void Dialog::newConnSlot()
{
    //如果不是第一次连接,先踢掉之前的连接
    if(socket !=NULL){
        socket->close();
    }
    //拿到与客户端进行连接的QTcpSocket对象(绿蛋)
    socket = server->nextPendingConnection();
    //建立断开连接的通知的信号槽
    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnectedSlot()));
    //建立读取消息的信号槽
    connect(socket,SIGNAL(readyRead()),this,SLOT(readReadSlot()));

    //拿到对面客户端的IP与端口号
    QString ip = socket->peerAddress().toString();
    quint16 port = socket->peerPort();
    //输出信息
    QString time = QDateTime::currentDateTime().toString("hh:mm:ss");
    ui->textBrowser->append(time);
    ui->textBrowser->append("新连接来了!");
    ui->textBrowser->append(ip.append(":").append(QString::number(port)));
    ui->textBrowser->append("");


}

void Dialog::disconnectedSlot()
{
    //拿到对面客户端的IP与端口号
    QString ip = socket->peerAddress().toString();
    quint16 port = socket->peerPort();
    //输出信息
    QString time = QDateTime::currentDateTime().toString("hh:mm:ss");
    ui->textBrowser->append(time);
    ui->textBrowser->append("老连接走了!");
    ui->textBrowser->append(ip.append(":").append(QString::number(port)));
    ui->textBrowser->append("");
}

void Dialog::readReadSlot()
{
    QTextStream input(socket);
    //读取数据
    QString msg = input.readAll();
    //展示
    ui->textBrowser->append(msg);
}

ui界面

 运行结果:

 

 

 

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

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

相关文章

[WiFi] WiFi 5G DFS机制及认证

DFS机制及认证 DFS是Dynamic Frequency Selection (DFS)&#xff0c;动态频率选择&#xff08;DFS&#xff09;是指允许未经许可的设备&#xff08;尤其是在室外操作的设备&#xff09;共享已分配给雷达系统的5GHz频段而不会对这些雷达造成干扰的机制。启用DFS功能后&#xff0…

PostGIS的安装与建库(Windows)

PostGIS的安装与建库(Windows) 文档目录 PostGIS的安装与建库(Windows)安装PostgreSQL安装PostGIS构建空间数据库 安装PostgreSQL 首先&#xff0c;以管理员身份运行 postgresql-13.5-1-windows-x64。(下面是安装包下载链接) 链接:https://pan.baidu.com/s/1vr6_zwOzW4UW6zwf6…

Backpropagation(反向传播)

是一种高效计算梯度下降的方法。 Chain Rule&#xff08;链式法则&#xff09; 定义了一个loss function是所有training data的loss之和。 考虑某一个neuron的情况 Forward Pass z对w的偏微分就是输入x。 Backward Pass Case1- Output Layer 假设两个红色的neuron已经是outpu…

声音合成——Foley Sound——DECASE项目——多模态智能感知与应用——课程学习(5)

文章目录 概述一、Approaches And Challenges生成的声音是什么类型训练模型使用的是什么特征原始音频Raw Audio频谱图Spectrograms 声音生成模型常用的结构生成模型的输入 二、Autoencoders Explained Easily自动编码器的通俗解释PCA和编码器的区别如何训练一个编码器Deep Auto…

深眸科技|机器视觉加速渗透各行各业,推进制造业智能制造进程

近年来&#xff0c;随着人工智能技术的不断发展&#xff0c;机器视觉技术作为其重要分支&#xff0c;加速渗透进我国制造业生产环节&#xff0c;覆盖从装配到检测等高端复杂领域&#xff0c;推进我国从制造大国迈向制造强国的进程。 机器视觉技术在工业生产过程中具有多种应用&…

域名历史查询工具-批量域名历史注册记录查询

批量备案域查询 在互联网时代&#xff0c;域名备案已经成为一项必要工作&#xff0c;但是批量备案域名是一项繁琐和费力的工作。为了帮助企业和个人轻松应对域名备案&#xff0c;出现了一种新型的解决方案——批量备案域名查询监控软件。 这种软件的最大优势是自动化&#xf…

域名备案批量查询工具-域名备案查询

为什么域名要备案 域名备案是一种互联网服务管理制度。其主要目的是加强互联网信息管理&#xff0c;维护网络安全和公共利益&#xff0c;规范网站的使用和运营行为。备案对于网站和域名的合法性和正常运营都具有重要的意义。没有备案的域名无法在大陆境内访问&#xff0c;并可…

linux发行家族和发行版及安装软件方式

在Linux平台下&#xff0c;软件包的类型可以划分为两类&#xff1a;源码包、二进制包&#xff1b; 一个软件要在Linux上执行&#xff0c;必须是二进制文件&#xff1b; 源码包&#xff1a;即程序软件的源代码&#xff08;一般也叫Tarball&#xff0c;即将软件的源码以tar打包后…

功能测试包含哪些测试?分别有什么作用?

功能测试包含哪些测试&#xff1f;功能测试主要包括链接测试、表单测试、搜索测试、删除测试、cookies、session测试、数据库测试等部分。功能测试对产品的各功能进行验证&#xff0c;根据功能测试用例&#xff0c;逐项测试&#xff0c;检查产品是否达到用户要求的功能。 功能…

WPS表格的IF与AND函数典型应用实例

HR人士在招聘时经常需要对面试人员进行三次面试都合格才给录取&#xff0c;如果单独使用一个IF函数没有办法进行三个成绩判断&#xff0c;这就需要使用IF函数结合AND函数配合起来使用。先看一下示例数据表&#xff0c;当初试、复试、终试三个成绩都大于80才返回录取。 先看一下…

第1章:项目管理概论

1、《项目管理知识体系指南》&#xff08;《指南》&#xff09;作为一部公认的项目管理标准&#xff0c;规定了在大多数时间适用于大多数项目的知识和做法。这些知识和做法&#xff1a; 答案&#xff1a;可供各种项目裁剪使用 2、《指南》是关于以下哪个的标准&#xff1f; …

ADS1299IPAGR 8通道、低噪声模拟前端,TPS7B7701QPWPRQ1单通道低压降稳压器(LDO)

ADS1299IPAGR 模拟前端&#xff08;AFE&#xff09;是8通道、低噪声、24位、同步采样Δ∑模数转换器 (ADC)。这些ADC配有内置可编程增益放大器 (PGA)、内部基准和板载振荡器。ADS1299-x集成了颅外脑电图 (EEG) 和心电图 (ECG) 应用所需的全部常用功能。凭借高集成度和卓越性能&…

TDengine 部署与使用----时序数据库

官网 通过 Docker 快速体验 TDengine | TDengine 文档 | 涛思数据 docker安装 拉取最新docker镜像 docker pull tdengine/tdengine:latest 然后执行 docker run -d -p 6030:6030 -p 6041:6041 -p 6043-6049:6043-6049 -p 6043-6049:6043-6049/udp tdengine/tdengine 查看容器…

VMware Aria Automation Config 8.12 - Aria Automation 的软件配置管理与安全性

VMware Aria Automation Config 8.12 - Aria Automation 的软件配置管理与安全性 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-aria-automation-config/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Aria Aut…

Shell——正则表达式

正则表达式的作用 通常用于判断语句中&#xff0c;用来检查某一字符串是否满足某一格式 正则表达式的构成 正则表达式是由普通字符与元字符组成 普通字符包括大小写字母、数字、标点符号及一些其他符号 元字符是指在正则表达式中具有特殊意义的专用字符&#xff0c;可以用…

零基础入门测试该学什么?最全整理,照着学就对了

零基础入门测试该学什么&#xff1f;最全整理&#xff0c;照着学就对了 于很多小白而言&#xff0c;想要转行软件测试岗位&#xff0c;却又怕自己从来没有接触过计算机&#xff0c;底子很薄弱&#xff0c;从而还没开始就打起了退堂鼓。也有许多初学者&#xff0c;在入门的过程…

虚拟化技术介绍-VMware和Docker的区别

都说今天是一个云时代&#xff0c;其实云的本质就是由基础架构提供商提供基础架构&#xff0c;应用开发商不再关心基础架构。我们可以类比人类刚刚发明电的时候&#xff0c;工厂需要自己建电站&#xff0c;而现在只需要电线和插座就可以使用电。云时代让我们可以在分钟、甚至秒…

ASEMI代理ADI亚德诺ADUM3211TRZ-RL7原厂芯片

编辑-Z ADUM3211TRZ-RL7参数描述&#xff1a; 型号&#xff1a;ADUM3211TRZ-RL7 数据速率&#xff1a;10 Mbps 传播延迟&#xff1a;50 ns 脉冲宽度失真&#xff1a;3 ns 脉冲宽度&#xff1a;100 ns 输出上升/下降时间&#xff1a;2.5 ns 供电电流&#xff1a;2.6 mA …

Google Play应用广告系列的转化跟踪

设置和了解我们应用的转化对于广告投放的成功至关重要。依赖错误或虚假数据&#xff0c;很容易影响我们的目标和投资回报。 无论我们运行的是什么活动&#xff0c;要做的第一件事就是将主要转化与其成本相关联&#xff1a; 1&#xff0c;应用安装活动侧重于安装和 CPI 或每次…

Gif动图怎么在线做?教你在线做gif动画图片

****  现在很多广告营销中gif动图非常的收欢迎&#xff0c;比传统的静态图片画面要生动丰富。但是&#xff0c;要如何制作gif动图宣传图片呢&#xff1f;小白也能操作吗&#xff1f; 一、什么工具能够在线制作gif动画图片&#xff1f; GIF中文网作为专业的gif制作&#xff…