QT网络编程TCP/UDP开发流程 制作网络调试助手

这篇具有很好参考价值的文章主要介绍了QT网络编程TCP/UDP开发流程 制作网络调试助手。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、开发基础知识

1、QT的网络编程: TCP和UDP

TCP编程需要用到俩个类: QTcpServer 和 QTcpSocket

QTcpSocket类提供了一个TCP套接字

  1. QTcpSocket是QAbstractSocket的一个子类,它允许您建立TCP连接和传输数据流
    注意:TCP套接字不能在QIODevice::Unbuffered模式下打开。

QTcpServer类提供一个基于tcp的服务器
2. 这个类可以接收传入的TCP连接。您可以指定端口或让QTcpServer自动选择一个端口。你可以监听一个特定的地址或所有机器的地址。
3. 调用listen()让服务器侦听传入的连接。然后,每当客户机连接到服务器时,都会发出newConnection()信号。
4. 调用nextPendingConnection()接受挂起的连接作为已连接的QTcpSocket。该函数返回一个指向QAbstractSocket::ConnectedState中的QTcpSocket的指针,您可以使用该指针

2、网络编程接口

1. listen

功能:设置监听数和分配端口,监听客户端连接

bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)

如果address为QHostAddress::Any,服务器将侦听所有网络接口;
为QHostAddress::LocalHost,IPv4本地主机地址,相当于QHostAddress(“127.0.0.1”)
当“port”为“0”时,系统自动分配端口
成功 true;失败 false

2. connect

功能:connect,是QT中的连接函数,将信号发送者sender对象中的信号signal与接受者receiver中的member槽函数联系起来。当指定信号signal时必须使用宏SIGNAL () ,当指定槽函数时必须使用宏SLOT()

connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context,	 
	Func2 slot, Qt::ConnectionType type = Qt::AutoConnection)

二、TCP编程

目标创建一个TCP服务端和一个TCP 客户端简单网络调试助手

1、TCP服务端实现流程

1. 创建项目

创建一个Qt Widgets Application项目QT网络编程TCP/UDP开发流程 制作网络调试助手 项目名称和位置都不要包含中文QT网络编程TCP/UDP开发流程 制作网络调试助手 基类选择QWidgetQT网络编程TCP/UDP开发流程 制作网络调试助手

2. UI设计
QT网络编程TCP/UDP开发流程 制作网络调试助手

接收窗口使用 QPlainTextEdit 并修改为只读
发送窗口使用 Line Edit

3. .h文件中包含头文件

#include <QTcpServer>
#include <QTcpSocket>

4. qmake文件中添加network

QT       += core gui network

5. Widget类构造函数中创建QTcpServer和QTcpSocket的对象用作监听套接字

tcpServer = new QTcpServer(this);
tcpSocket = new QTcpSocket(this);

tcpServer 和 tcpSocket 对象指针需要在Widget类中声明

QTcpServer *tcpServer;  
QTcpSocket *tcpSocket;

6. 使用listen()方法监听网卡的ip和端口(打开服务器)
侦听IPv4和IPv6接口,端口为portEdit输入的内容

void Widget::on_openBt_clicked()
{
    tcpServer->listen(QHostAddress::Any, ui->portEdit->text().toUInt());
}

7. 如果有新的连接过来,并且连接成功,服务器会触发newConnection()信号,通过槽函数取出连接成功的socket

connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection_Slot())); //连接请求到来,触发newConnection信号,并回调槽函数

void Widget::newConnection_Slot()
{
    while (tcpServer->hasPendingConnections()) //有待连接请求
    {
        tcpSocket = tcpServer->nextPendingConnection();	//连接并返回套接字
        connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot())); //套接字有数据到来触发信号readyRead(),回调槽函数
    }
}

8. 如果有数据成功传送过来,对方的通信套接字QTcpSocket会触发readyRead()信号,在槽函数可以进行读取

void Widget::readyRead_Slot()
{
    QString buf = tcpSocket->readAll();	//读数据
    ui->recvEdit->appendPlainText(buf);	//追加显示
}

9. 发送数据

void Widget::on_sendBt_clicked()
{
    tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
}

10. 关闭套接字(关闭服务器)

void Widget::on_closeButton_clicked()
{
    tcpSocket->close();
}

2、TCP客户端实现流程

1. 创建项目
基类选择QWidget
2. UI设计
QT网络编程TCP/UDP开发流程 制作网络调试助手

3. .h文件中包含头文件

#include <QTcpServer>
#include <QTcpSocket>

4. qmake文件中添加network

QT       += core gui network

5. Widget类构造函数中创建QTcpSocket的对象用作监听套接字

tcpSocket = new QTcpSocket(this);

tcpSocket 对象指针需要在Widget类中声明

QTcpSocket *tcpSocket;

6. connectTohost()绑定ip和端口号进行连接,连接成功会触发connected()信号,将该信号与槽函数关联

void Widget::on_openBt_clicked()
{
    tcpSocket->connectToHost(ui->ipEdit->text(), ui->portEdit->text().toUInt());
    connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected_Slot()));
}

7. readyRead()信号和槽函数关联

void Widget::connected_Slot()
{
    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot()));
}

8. 读数据

void Widget::readyRead_Slot()
{
    QString buf = tcpSocket->readAll();
    ui->recvEdit->appendPlainText(buf);
}

9. 发送数据

void Widget::on_sendBt_clicked()
{
    tcpSocket->write(ui->sendEdit->text().toLocal8Bit());
}

10. 关闭套接字

void Widget::on_sendBt_clicked()
{
    tcpSocket->write(ui->sendEdit->text().toLocal8Bit());
}

三、UDP编程

udp通信这里不分服务端和客户端

1. 创建项目
基类选择QWidget
2. UI设计
QT网络编程TCP/UDP开发流程 制作网络调试助手
3. .h文件中包含头文件

#include <QUdpSocket>

4. qmake文件中添加network

QT       += core gui network

5. Widget类构造函数中创建QTcpSocket的对象用作监听套接字

udpSocket = new QUdpSocket(this); //获取套接字

udpsocket对象指针需要在Widget类中声明

QUdpSocket *udpSocket;

6. bind()设置本地端口号,准备读信号与槽函数关联(打开udp连接)

void Widget::on_openBt_clicked()
{
    udpSocket->bind(ui->localPort->text().toUInt());  //绑定本地端口

    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_slot()));  //准备读信号与槽函数关联
}

7. 读数据

void Widget::readyRead_slot()
{
    while(udpSocket->hasPendingDatagrams()) {   //udp与tcp不同,udp需要判断数据是否读完
        QByteArray array;
        array.resize(udpSocket->pendingDatagramSize()); //调整array数组大小与数据报大小一致
        udpSocket->readDatagram(array.data(), array.size()); //读取数据报到array.data中、

        QString buf = array.data(); //将数据类型转换成string类型
        ui->recvEdit->appendPlainText(buf); //将数据显示到接收窗口
    }
}

8. 发送数据

void Widget::on_sendBt_clicked()
{
    QHostAddress address;

    address.setAddress(ui->aimIp->text());
    udpSocket->writeDatagram(ui->sendEdit->text().toLocal8Bit().data(), //发送内容 const char *
                             ui->sendEdit->text().length(), //内容长度 qint64
                             address, //目标IP const QHostAddress &
                             ui->aimPort->text().toUInt()); //目标端口 quint16
}
  1. 关闭套接字
udpSocket->close();

四、源码

1. TCP服务端

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QString>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

    QTcpServer *tcpServer;  //声明套接字
    QTcpSocket *tcpSocket;

private slots:  //槽函数声明
    void newConnection_Slot();
    void readyRead_Slot();
    void on_openBt_clicked();
    void on_closeButton_clicked();
    void on_sendBt_clicked();

private:
    Ui::Widget *ui;
};

#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);

    tcpServer = new QTcpServer(this);   //获取套接字
    tcpSocket = new QTcpSocket(this);

    connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection_Slot())); //新连接请求信号与连接槽函数关联
}

void Widget::newConnection_Slot()
{
    while (tcpServer->hasPendingConnections())  //有待连接请求
    {
        tcpSocket = tcpServer->nextPendingConnection(); //连接并返回套接字
        connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot())); //读准备信号与读槽函数关联
    }
}

void Widget::readyRead_Slot()   //读取数据并显示到接收窗口
{
    QString buf = tcpSocket->readAll();
    ui->recvEdit->appendPlainText(buf);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_openBt_clicked()   //打开服务器
{
    tcpServer->listen(QHostAddress::Any, ui->portEdit->text().toUInt()); //监听接口,设计端口号
}

void Widget::on_closeButton_clicked()   //关闭套接字
{
    tcpSocket->close();
}

void Widget::on_sendBt_clicked()   //发送数据
{
    tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
}

2. TCP客户端

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>
#include <QString>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);

    QTcpSocket *tcpSocket;

    ~Widget();

private slots:
    void connected_Slot();
    void readyRead_Slot();
    void on_closeBt_clicked();
    void on_sendBt_clicked();
    void on_openBt_clicked();

private:
    Ui::Widget *ui;
};

#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);

    tcpSocket = new QTcpSocket(this);	//获取套接字
}

Widget::~Widget()
{
    delete ui;
}

void Widget::connected_Slot()
{
    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot()));	//读准备信号关联槽函数
}

void Widget::readyRead_Slot()	//读数据
{
    QString buf = tcpSocket->readAll();
    ui->recvEdit->appendPlainText(buf);
}

void Widget::on_sendBt_clicked()	//发送数据
{
    tcpSocket->write(ui->sendEdit->text().toLocal8Bit());
}

void Widget::on_closeBt_clicked()	//关闭套接字
{
    tcpSocket->close();
}

void Widget::on_openBt_clicked()	//连接服务器,连接成功信号和槽函数关联
{
    tcpSocket->connectToHost(ui->ipEdit->text(), ui->portEdit->text().toUInt());
    connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected_Slot()));  //可替换如下
    //connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot()));
}

3. UDP

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QUdpSocket>
#include <QString>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

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

    QUdpSocket *udpSocket;

private slots:
    void on_openBt_clicked();
    void readyRead_slot();
    void on_sendBt_clicked();
    void on_closeBt_clicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

widget.cpp文章来源地址https://www.toymoban.com/news/detail-402884.html

#include "widget.h"
#include "ui_widget.h"

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

    udpSocket = new QUdpSocket(this); //获取套接字
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_openBt_clicked()
{
    udpSocket->bind(ui->localPort->text().toUInt());  //绑定本地端口

    connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_slot()));  //准备读信号与槽函数关联
}

void Widget::readyRead_slot()
{
    while(udpSocket->hasPendingDatagrams()) {   //udp与tcp不同,udp需要判断数据是否读完
        QByteArray array;
        array.resize(udpSocket->pendingDatagramSize()); //调整array数组大小与数据报大小一致
        udpSocket->readDatagram(array.data(), array.size()); //读取数据报到array.data中、

        QString buf = array.data(); //将数据类型转换成string类型
        ui->recvEdit->appendPlainText(buf); //将数据显示到接收窗口
    }
}

void Widget::on_sendBt_clicked()
{
    QHostAddress address;

    address.setAddress(ui->aimIp->text());
    udpSocket->writeDatagram(ui->sendEdit->text().toLocal8Bit().data(), //发送内容 const char *
                             ui->sendEdit->text().length(), //内容长度 qint64
                             address, //目标IP const QHostAddress &
                             ui->aimPort->text().toUInt()); //目标端口 quint16
}

void Widget::on_closeBt_clicked()
{
    udpSocket->close(); //关闭套接字
}

到了这里,关于QT网络编程TCP/UDP开发流程 制作网络调试助手的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】6.网络编程:网络编程(TCP&UDP)

    网络编程是C++ API操作中很重要的一部分,包含 TCP 和 UDP 。 网络传输模型可以抽象为7个层: 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层 。 但在使用TCP/IP协议时,可以简化为这4层: 网络接口、网络层、传输层、应用层 。 TCP:可靠传输,三次握手建立

    2024年02月16日
    浏览(33)
  • 网络编程 —— TCP 和 UDP 编程详解

    目录 网络编程主要函数介绍 1. socket 函数 2. bind 函数 3. listen 函数 4. accept 函数 5. connect 函数 6. send 函数 7. recv 函数 8. recvfrom 函数 9. sendto 函数 TCP 和 UDP 原理上的区别 TCP 编程 服务端代码: 客户端代码: UDP 编程 服务端代码: 客户端代码: 1. socket 函数 int socket(int domain, int

    2024年02月04日
    浏览(35)
  • 网络编程、UDP、TCP

    就是将地理位置不同的具有独立功能的多台计算及外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件以及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统 传播交流信息、数据交换、通信 1.如何准确定位网络上的一台主机 192.xxx.xx.xx:端

    2024年03月10日
    浏览(39)
  • 基于TCP、UDP网络编程

    应用层 : 应用程序拿到数据怎么用 传输层 : 负责关注传输过程中起点和终点 网络层 :负责整个传输过程中的路线规划 数据链路层 :负责相邻节点之间的数据传输 物理层 : 基础设施,硬件设备 程序员写网络程序,主要编写的应用层代码,真正要发这个数据,调用下层协

    2024年02月07日
    浏览(40)
  • UDP和TCP网络编程

    特点: 无连接:发送数据前不需要建立连接。 不可靠:没有重发机制,无法保证数据的可靠性和顺序。 无拥塞控制:发送方发送数据的速度受限于网络的带宽。 快速:由于没有连接建立和拥塞控制的处理,UDP的传输速度通常比TCP快。 简单:UDP协议的头部较小,仅有8个字节

    2024年02月11日
    浏览(38)
  • TCP和UDP网络编程

    TCP和UDP协议是TCP/IP协议的核心。 TCP 传输协议:TCP 协议是一TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠

    2023年04月08日
    浏览(36)
  • 【网络编程】TCP,UDP协议详解

    小亭子正在努力的学习编程,接下来将开启javaEE的学习~~ 分享的文章都是学习的笔记和感悟,如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话,烦请点赞关注支持一波, 感激不尽~~   目录 前言 TCP协议 TCP协议特点 TCP协议通信场景 TCP协议的几个重要机制 一、

    2023年04月19日
    浏览(45)
  • 网络编程(TCP与UDP协议)

    Java是 Internet 上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序。 Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在 Java 的本机安装系统里,由 JVM 进行控制。并且 Java 实现了一个跨平台的网络库, 程序

    2023年04月27日
    浏览(43)
  • Java网络编程(UDP、TCP)

    在网络通信协议下,不同计算机上运行的程序,进行的数据传输。 应用场景:即时通信、网游对战、金融证券、国际贸易、邮件、等等。 不管是什么场景,都是计算机跟计算机之间通过网络进行数据传输。 Java中可以使用java.net包下的技术轻松开发出常见的网络应用程序。

    2024年02月05日
    浏览(53)
  • 【Java学习笔记】 68 - 网络——TCP编程、UDP编程

    https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter21/src 目录 项目代码 网络 一、网络相关概念 1.网络通讯 2.网络 3.IP地址 4.域名 5.端口号 6.网络通讯协议 TCP协议:传输控制协议 UDP协议: 二、InetAddress类 1.相关方法 三、Socket 1.基本介绍 2.TCP网络通信编程 基本介绍 应用案例

    2024年02月04日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包