【QT】TCP通信(QTcpServer 和 QTcpSocket)

QT:Socket通讯(TCP) 学习笔记 阅读详情

1. TCP通信概述

TCP是一种被大多数Internet网络协议(如HTTP)用于数据传输的低级网络协议,它是可靠的、面向流、面向连接的传输协议,特别适合于连续数据传输。

TCP通信必须先建立TCP连接,分为服务器端和客户端。
Qt提供QTcpServer类和QTcpSocket类用于建立TCP通信。
服务器端必须使用QTcpServer用于端口监听,建立服务器;QTcpSocket用于建立连接后使用套接字进行通信。

2. QTcpServer

QTcpServer继承于QObject

2.1 公共函数

void close() 关闭服务器,停止网络监听

bool listen(address, port) 在给定IP地址和端口上开始监听,若成功返回true。address = QHostAddress addr(IP)

bool isListening() 返回true表示服务器处于监听状态

QTcpSocket* nextPendingConnection() 返回下一个等待接入的连接。套接字是作为服务器的子节点创建的,这意味着当QTcpServer对象被销毁时,它将被自动删除。在使用完对象后显式地删除它,以避免浪费内存。如果在没有挂起连接时调用此函数,则返回0。注意:返回的QTcpSocket对象不能从其他线程使用。如果您想使用来自另一个线程的传入连接,则需要重写incomingConnection()。

QHostAddress serverAddress() 若服务器处于监听状态,返回服务器地址

quint16 serverPort() 若服务器处于监听状态,返回服务器监听端口

bool waitForNewConnection() 以阻塞的方式等待新的连接

2.2 信号

void acceptError(QAbstractSocket::SocketError socketError) 当接受一个新的连接发生错误时发射此信号,参数socketError描述了错误信息

void newConnection() 当有新的连接时发射此信号

2.3 保护函数

void incomingConnection(qintptr socketDescriptor) 当有新的连接可用时,QTcpServer内部调用此函数,创建一个QTcpServer对象,添加到内部可用新连接列表,然后发射newConnection()信号。用户若从QTcpServer继承定义类,可以重定义此函数,但必须调用addPendingConnection()。qintptr根据系统类型不同而不同,32位为qint32,64位为qint64。

void addPendingConnection(QTcpSocket* socket) 由incomingConnection()调用,将创建的QTcpSocket添加到内部新可用连接列表。

3. QTcpSocket

QTcpSocket是从QIODevice间接继承的

QIODevice -> QAbstractSocket -> QTcpSocket

QTcpSocket类除了构造和析构,其他函数都是从QAbstractSocket继承或重定义的

3.1 公共函数

void connectToHost(QHostAddress& address, quint16 port) 以异步方式连接到指定IP地址和端口的TCP服务器,连接成功会发送connected()信号

void disconnectFromHost() 断开socket,关闭成功后会发射disconnected()信号

bool waitForConnected() 等待直到建立socket连接

bool waitForDisconnected() 等待直到断开socket连接

QHostAddress localAddress() 返回本socket的地址

quint16 localPort 返回本socket的端口

QHostAddress peerAddress() 在已连接状态下,返回对方socket的地址

QString peerName() 返回connectToHost()连接到的对方的主机名

quint16 peerPort() 在已连接状态下,返回对方socket的端口

qint64 readBufferSize() 返回内部读取缓冲区的大小,该大小决定了read()和realAll()函数能读出的数据的大小

void setReadBufferSize(qint64 size) 设置内部读取缓冲区的大小

qint64 bytesAvailable() 返回需要读取的缓冲区的数据的字节数

bool canReadLine() 如果有行数据要从socket缓冲区读取,则返回true

SocketState state() 返回socket当前的状态

3.2 信号

void connected() connectToHost()成功连接到服务器后会发射此信号

void disconnected() 断开socket连接后会发射此信号

void error(QAbstractSocket::SocketError socketError) 当socket发生错误时会发射此信号

void hostFound() 调用connectToHost()找到主机后会发射此信号

void stateChanged(QAbstractSocket::SocketState socketState) 当socket状态发生变化时会发射此信号,参数socketState表示socket当前的状态

void readyRead() 当缓冲区有新数据需要读取时会发射此信号,在此信号的槽函数里读取缓冲区的数据

4. 代码示例

4.1 服务器端

使用Qt网络模块,需要在配置文件.pro中添加:

Qt += network

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QAction>
#include <QCloseEvent>
#include <QComboBox>
#include <QGridLayout>
#include <QHostInfo>
#include <QLabel>
#include <QLineEdit>
#include <QMainWindow>
#include <QMessageBox>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QSpinBox>
#include <QTcpServer>
#include <QTcpSocket>

namespace Ui {
   
   
    class MainWindow;
}

class MainWindow : public QMainWindow {
   
   
    Q_OBJECT

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

protected:
    void closeEvent(QCloseEvent* event);

private slots:
    //工具栏按钮
    void slotActStartTriggered();
    void slotActStopTriggered();
    void slotActClearTriggered();
    void slotActQuitTriggered();

    //界面按钮
    void slotBtnSendClicked();

    //自定义槽函数
    void slotNewConnection();       // QTcpServer的newConnection()信号
    void slotClientConnected();     //客户端socket连接
    void slotClientDisconnected();  //客户端socket断开连接
    void slotSocketStateChange(QAbstractSocket::SocketState socketState);
    void slotSocketReadyRead();  //读取socket传入的数据

private:
    Ui::MainWindow* ui;

    QAction* m_pActStartListen;
    QAction* m_pActStopListen;
    QAction* m_pActClearText;
    QAction* m_pActQuit;
    QWidget* m_pCentralWidget;
    QGridLayout* m_pGridLayout;
    QLabel* m_pLabel1;
    QComboBox* m_pComBoxIP;
    QLabel* m_pLabel2;
    QSpinBox* m_pSpinBoxPort;
    QLineEdit* m_pLineEdit;
    QPushButton* m_pBtnSend;
    QPlainTextEdit* m_pPlainText;
    QLabel* m_pLabListenStatus;  //状态栏标签
    QLabel* m_pLabSocketState;   //状态栏标签
    QTcpServer* m_pTcpServer;    // TCP服务器
    QTcpSocket* m_pTcpSocket;    // TCP通信的socket

    QString getLocalIP();  //获取本机IP地址
};

#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);
    this->setWindowTitle(QStringLiteral("TCP服务端"));
    ui->menuBar->hide();

    //工具栏
    ui->mainToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);  //设置工具栏显示风格(图标在上文字在下)
    m_pActStartListen = new QAction(QIcon(":/new/prefix1/res/开始.png"), QStringLiteral("开始监听"), this);
    m_pActStopListen = new QAction(QIcon(":/new/prefix1/res/暂停.png"), QStringLiteral("停止监听"), this);
    m_pActClearText = new QAction(QIcon(":/new/prefix1/res/清空数据.png"), QStringLiteral("清空文本框"), this);
    m_pActQuit = new QAction(QIcon(":/new/prefix1/res/退出.png"), QStringLiteral("退出"), this);
    ui->mainToolBar->addAction(m_pActStartListen);
    ui->mainToolBar->addAction(m_pActStopListen);
    ui->mainToolBar->addAction(m_pActClearText);
    ui->mainToolBar->addSeparator();
    ui->mainToolBar->addAction(m_pActQuit);

    //界面布局
    m_pCentralWidget = new QWidget(this);
    m_pGridLayout = new QGridLayout(m_pCentralWidget);
    m_pLabel1 = new QLabel(QStringLiteral("监听地址"), m_pCentralWidget);  //父对象为新的widget
    // label对象被析构了,所以不会在界面显示。label1需要作为成员变量才可显示或者用指针
    //    QLabel label1;
    //    label1.setText("监听地址");
    m_pComBoxIP = new QComboBox(m_pCentralWidget);
    // m_pComBoxIP->addItem("192.168.1.104");  // QComboBox设置默认项必须添加项
    //必须先add项才能操作下面
    //    comBoxAddr->setCurrentIndex(0);
    //    comBoxAddr->setCurrentText("192.168.1.104");
    m_pLabel2 = new QLabel(QStringLiteral("监听端口"), m_pCentralWidget);
    m_pSpinBoxPort = new QSpinBox(m_pCentralWidget);
    m_pSpinBoxPort->setMinimum(1);
    m_pSpinBoxPort->setMaximum(65535);  //端口范围1~65535
    m_pLineEdit = new QLineEdit(m_pCentralWidget);
    m_pBtnSend = new QPushButto
Qt开发:QTcpSocket的详解 QTcpSocket 是 Qt 网络模块中用于实现基于 TCP 协议的客户端通信的类。它提供了一个面向流的接口,允许程序通过套接字连接到远程主机,发送和接收数据。 阅读详情

相关推荐

Qt学习(十四)—— 网络通信之TCP

TCP有两个套接字,一个是socket,监听套接字,负责监听,一个是accept,通信套接字,负责建立连接(链接)? bind 绑定 比如打电话需要知道电话号码 绑定的作用可以简单认为是固定一个端口,如果不固定,那么这个端口是随机的。 listen是服务端用来监听的。 总之服务端要完成的就是:socket、bind、listen。 客户端也有socket套接字 它需要主动链接,所以还有一个connect 客户端主动向服务端发起connect链接。 服务端有accept确定建立好了链接,没有建立链接的时候它是

饭的笔记本 3583

Qt实现TCP通信

Qt要实现TCP通信需要两个类,第一个是服务器端,需要用到QTcpServer类,第二个是客户端,需要用到QTcpSocket类。另外,要想在Qt中进行网络通信,需要在pro文件中加入network模块。C语言建立Tcp通信时,需要经历“socket函数创建套接字-->bind绑定地址结构-->listen设置最大监听数-->accept监听来自客户端的连接”这几个阶段,QTcpServer中的listen函数就相当于C语言中bind和listen的功能。

2301_81261654的博客 1577

Qt网络通信(TCP/UDP)

将数据报发送到广播地址,同一网络中的所有设备都会接收到广播数据报,但只有那些运行了相应接收程序并监听特定端口的设备才会处理这些数据报。创建QTcpServer对象---启动服务器监听---处理新连接请求---数据传输---关闭连接。创建QTcpSocket对象---连接服务器---数据传输---关闭连接。:发送端向一个特定的接收端发送数据,需要指定接收端的IP地址和端口号。创建套接字---绑定端口---接收数据---关闭套接字。创建套接字---发送数据---关闭套接字。

2301_82023822的博客 1965

基于QT的TCP通信

利用QTcpServer类以及QTcpSocket类进行TCP通信,实现了行数据的传输。

weixin_43479242的博客 2694

【QT开发】TCP服务器QTcpServer类详解及实战应用

QTcpServer 是 Qt 提供的一个功能强大且灵活的 TCP 服务器类,通过本篇文章的学习,你应该对 QTcpServer 有了全面的理解,能够在自己的项目中正确使用它。QTcpServer 在用户界面中帮助你更好地管理和处理客户端连接,实现高效的 TCP 通信服务,有助于创建用户友好和高效的网络应用场景。

科技改变人类,技术成就未来 3171

PHY6252开发实战:从零构建BLE串口透传应用

本文详细介绍了PHY6252开发板在BLE串口透传应用中的实战经验,包括开发环境搭建、BLE串口透传例程解析、AT指令集实现与扩展、数据透传机制优化以及常见问题排查指南。通过智能家居遥控器项目案例,展示了PHY6252在低功耗物联网设备开发中的实际应用。

weixin_29183637的博客 304

Loupe Browser实战指南:解锁10xGenomics单细胞数据的可视化奥秘

本文提供了Loupe Browser的实战指南,帮助用户无需编程即可探索和可视化10xGenomics单细胞数据。文章详细介绍了从数据导入、界面导航到细胞亚群鉴定、差异基因分析的核心操作流程,并分享了高级技巧与避坑指南,是快速上手这一强大可视化工具的必备参考。

weixin_29313423的博客 204

当迁移学习遇见室内定位:基于UJIIndoorLoc的跨场景适配实践

本文探讨了迁移学习在跨建筑室内定位中的应用,重点解析了UJIIndoorLoc数据集的特性及其在解决设备差异和环境变化中的关键作用。通过特征工程、迁移学习策略和小样本微调技术,显著提升了定位模型的跨场景适配能力,为实际部署提供了有效解决方案。

weixin_29038155的博客 392

从RJPG到温度地图:基于大疆TSDK的热红外数据精准处理与Pix4D拼接实战

本文详细解析了如何利用大疆TSDK将无人机拍摄的热红外RJPG图像精准转换为带有地理坐标的温度TIFF文件,并完成Pix4D拼接生成正射温度地图的全流程。文章重点阐述了辐射定标的原理、TSDK关键参数(测量距离、湿度、发射率、反射温度)的设置与微调方法,以及Pix4D处理中的常见报错解决方案,旨在帮助用户实现从原始数据到可分析温度地图的精准处理。

docker7nomad的博客 457

SAP系统中PP模块全配置文档

配置路径IMG>SAP NetWeaver>常规设置>维护日历>工厂日历事务代码SCAL要求传输工厂代码描述日历代码日历描述起始日期星期一星期二星期三星期四星期五星期六星期日有效开始日期有效结束日期1000南微医学工厂MT南微医学工厂日历√√√√√√√201820502.4定义工厂配置路径IMG>生产>物料清单>常规数据>定义BOM状态事务代码OS23要求传输配置路径IMG>生产>主数据>资源>常规数据>标准值>定义参数。

yanzibing99的博客 1885

VMware VSAN 高级参数介绍(测试用)

VSAN 的策略驱动让我们看到了VSAN无穷的潜力,其设计思路相当新颖,在一个基础资源池上使用策略就能实现不同对象的区分服务,而目前没有其他厂家能到VMware这样的高度。 VSAN 呈现给用户配置很简单,但实际上设计及后台比较复杂。笔者无意间发现了VSAN的隐藏高级参数设置,有很多好玩的选项想分享出来。这些参数全部是针对每主机进行设置的。VSAN 中有很多默认设置,这些设置应该都是研发人员多次测试得出的最优值,修改可能导致环境异常,并不建议修改! 目录 参数1:全闪配置下 SSD 写缓存最大.

山水牧羊 2022

7、Python高光谱分析工具(PyHAT)简介

Python高光谱分析工具(PyHAT)是一个开源、跨平台的Python库及图形用户界面,用于行星光谱数据的可视化与分析。它支持多种高光谱传感器数据,如火星勘测轨道飞行器的CRISM、月船1号的M3以及SELENE Kaguya SP点光谱仪,提供预处理、衍生产品生成、统计学习和机器学习分析功能。PyHAT基于Pandas和NumPy构建,兼容Jupyter和QGIS环境,旨在解决现有光谱分析方法缺乏开源实现、难以探索性分析和算法分散的问题。其模块化架构涵盖数据输入/输出、通用光谱变换、测绘与点观测工具及高

aa123的博客 131

[VT虚拟化驱动] 定义类及初始化内存区域

文章目录前言框架整体流程图类的定义初始化内存区域本章代码 前言 为什么不用C而用C++呢? 在单核的情况下,用C还比较方便些,但在多核的情况下,每个核心都需要分配有对应的一个VMX区域,VMCS区域,MsrBitmap区域和栈空间,以及对应的初始化函数,如果使用安装DPC回调的方式在多核情况下进行初始化,只使用同一个初始化函数,当函数被多个CPU核心同时执行,会出现很多意想不到的的错误,我用自旋锁试了一下是依照各种错误,所以果断用C++了,把这些每个核心都需要一份的封装到一个类里 框架整体流程图 类的定义

吾无法无天的博客 1832

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: 【QT】QHostInfo 和 QNetworkInterface 的使用
下一篇: 【QT】UDP通信QUdpSocket(单播、广播、组播)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值