QT网络编程——TCP

news/发布时间2024/9/20 8:50:34

TCP

TCP(Transmission Control Protocol,传输控制协议)是一个用于数据传输的低层的网络协议,多个互联网协议(包括 HTTP 和 FTP)都是基于 TCP 协议的。它是可靠的、面向流、面向连接的传输协议,特别适合连续数据的传输。

TCP 通信必须先建立连接,分为客户端和服务端,也就是所谓的 C/S(Client/Server)模型,如图:

在这里插入图片描述

客户端

客户端使用 QTcpSocket 与 TCP 服务器建立连接并通信。

QTcpSocket 类除了构造函数和析构函数,其他函数都是从 QAbstractSocket 继承或重定义的。QAbstractSocket 用于 TCP 通信的主要接口函数如图:

在这里插入图片描述

客户端的 QTcpSocket 实例首先通过 connectToHost() 尝试连接到服务器,需要指定服务器的 IP 地址和端口号。connectToHost() 是异步方式连接服务器,不会阻塞程序运行,连接后发射 connected() 信号。

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpSocket>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void onConnected();void onDisconnected();void onReadyRead();void on_btnConnect_clicked();void on_btnSendMsg_clicked();private:Ui::Widget *ui;QTcpSocket *m_client{};
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "./ui_widget.h"#include <QHostAddress>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);setWindowTitle("客户端");m_client = new QTcpSocket(this);connect(m_client, &QTcpSocket::connected, this, &Widget::onConnected);connect(m_client, &QTcpSocket::disconnected, this, &Widget::onDisconnected);connect(m_client, &QTcpSocket::readyRead, this, &Widget::onReadyRead);
}Widget::~Widget()
{m_client->abort();delete ui;
}void Widget::onConnected()
{ui->labConnectState->setText("Connecting");
}void Widget::onDisconnected()
{ui->labConnectState->setText("Disconnect");
}void Widget::onReadyRead()
{ui->textEditRecv->setText(m_client->readAll());
}void Widget::on_btnConnect_clicked()
{QString str = ui->btnConnect->text();if (str == "Connect") {ui->btnConnect->setText("Disconnect");if (m_client->state() == QAbstractSocket::SocketState::ConnectingState) {m_client->close();}QString address = ui->leAddress->text();QString port = ui->lePort->text();m_client->connectToHost(QHostAddress(address), port.toInt());} else {ui->btnConnect->setText("Connect");m_client->close();}
}void Widget::on_btnSendMsg_clicked()
{QString msg = ui->textEditSend->toPlainText();m_client->write(msg.toLocal8Bit());
}

界面如图:

在这里插入图片描述

服务端

服务端程序必须使用 QTcpServer 进行端口监听,建立服务器。QTcpSocket 用于建立连接后使用套接字。

QTcpServer 是从 QObject 继承的类,它主要用于服务器建立网络监听,创建网络 Socket 连接。QTcpServer 类的主要接口函数如下所示:

在这里插入图片描述

服务端可以使用 QTcpServer::listen() 指定监听的 IP 地址和端口,一般一个服务程序只监听某个端口的网络连接。

当有新的客户端接入时,QTcpServer 内部的 incomingConnection() 函数会创建一个与客户端连接的 QTcpSocket 对象,然后发出信号 newConnection()。可以使用 nextPendingConnection() 接受客户端的连接,然后使用 QTcpSocket 与客户端通信。所以在客户端与服务端建立连接后,具体的数据通信是通过 QTcpSocket 完成的。

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void onNewConnection();void onReadyRead();void onClientDisconnected();void on_btnClose_clicked();void on_btnSendMsg_clicked();private:Ui::Widget *ui;QTcpServer *m_server{};QTcpSocket *m_socket{};
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "./ui_widget.h"#include <QHostAddress>
#include <QHostInfo>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);setWindowTitle("服务端");// 获取本地 ipQString ip;QHostInfo info = QHostInfo::fromName(QHostInfo::localHostName());for (auto &address : info.addresses()) {if (address != QHostAddress::LocalHost && address.toIPv4Address()) {ip = address.toString();break;}}ui->leAddress->setText(ip);ui->lePort->setText("1234");m_server = new QTcpServer(this);m_server->listen(QHostAddress::Any, 1234);connect(m_server, &QTcpServer::newConnection, this, &Widget::onNewConnection);
}Widget::~Widget()
{delete ui;
}void Widget::onNewConnection()
{m_socket = m_server->nextPendingConnection();// 告知客户端连接成功m_socket->write("Congratulations on successfully connecting !");connect(m_socket, &QTcpSocket::readyRead, this, &Widget::onReadyRead);connect(m_socket, &QTcpSocket::disconnected, this, &Widget::onClientDisconnected);// 更新连接状态显示ui->labConnectState->setText(QString("new connection %1 %2").arg(m_socket->peerAddress().toString()).arg(m_socket->peerPort()));
}void Widget::onReadyRead()
{ui->textEditRecv->setText(m_socket->readAll());
}void Widget::onClientDisconnected()
{ui->labConnectState->setText(QString("%1 %2 disconnected").arg(m_socket->peerAddress().toString()).arg(m_socket->peerPort()));
}void Widget::on_btnClose_clicked()
{m_server->close();
}void Widget::on_btnSendMsg_clicked()
{if (!m_socket)return;QString msg = ui->textEditSend->toPlainText();m_socket->write(msg.toLocal8Bit());
}

界面如图:

在这里插入图片描述

总结

本文只简单演示了 TCP 通信的基本原理。服务端只允许一个客户端连接。然而,一般的 TCP 服务器程序允许多个客户端接入,博主将在其他文章中进行讲解。

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

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

相关文章

《迷失方阵》问题

迷失方阵 给你一个N*M的方阵&#xff0c;你能告诉它这个方阵有多少个正方形吗&#xff1f; eg&#xff1a;1x1矩阵 1个正方形 2x3矩阵 8个正方形 代码很简洁&#xff0c;但是数学规律需要多拿笔画一下&#xff0c;才能发现。 #include<stdio.h> #include<math.h> …

安卓cpu内存监控,大厂首发

开头 很多人工作了十年&#xff0c;但只是用一年的工作经验做了十年而已。 高级工程师一直是市场所需要的&#xff0c;然而很多初级工程师在进阶高级工程师的过程中一直是一个瓶颈。 移动研发在最近两年可以说越来越趋于稳定&#xff0c;因为越来越多人开始学习Android开发&…

Transformer之Residuals Decoder

The Residuals 我们需要提到的编码器架构中的一个细节是&#xff0c;每个编码器中的每个子层(self-attention,&#xff0c;ffnn)周围都有一个残余连接&#xff0c;然后是 layer-normalization 步骤。 如果我们要可视化向量和与 self attention 相关的 layer-norm 运算&#x…

2024.02.29作业

1. TCP模型 server #include "test.h"#define SER_IP "192.168.191.128" #define SER_PORT 9999int main(int argc, char const *argv[]) {int sfd -1;sfd socket(AF_INET, SOCK_STREAM, 0);if (-1 sfd){perror("socket error");return -1;…

Linux磁盘设备LVM介绍和常用场景说明

Linux常见的物理设备数据备份和负载均衡模式 1. LVM技术说明2. 相关概念3. 常用命令3.1 安装lvm命令3.2 创建分区3.3 格式化成LVM3.4 其他格式化 4. 常用场景4.1 创建LVM并挂载4.2 LVM扩容4.2.1 xfs扩容4.2.2 ext4扩容 4.2 缩减逻辑卷lv4.3 缩减vg&#xff1a;&#xff08;迁移…

手机通用便签APP哪个比较好用?

手机通用便签APP哪个比较好用&#xff1f;随着现代科技的不断发展&#xff0c;手机的更新换代频率是比较快的&#xff0c;基本两三年就会换新手机。其中Android和iOS系统为手机主要使用系统&#xff0c;有些用户在使用一个系统腻了后&#xff0c;通常想更换另一个系统的品牌手机…

TCP/UDP模型:2024/2/29

作业1&#xff1a;TCP模型 服务器端&#xff1a; #include <myhead.h> #define SER_IP "192.168.199.129" #define SER_PORT 8899int main(int argc, const char *argv[]) {//1.创建用于连接的套接字文件int sfdsocket(AF_INET,SOCK_STREAM,0);if(sfd-1){per…

内网搭建mysql8.0并搭建主从复制详细教程!!!

一、安装mysql 1.1 mysql下载链接&#xff1a; https://downloads.mysql.com/archives/community/ 1.2 解压包并创建相应的数据目录 tar -xvf mysql-8.2.0-linux-glibc2.28-x86_64.tar.xz -C /usr/local cd /usr/local/ mv mysql-8.2.0-linux-glibc2.28-x86_64/ mysql mkdir…

06|Mysql内部组件结构

1. 连接器 客户端要向mysql发起通信都必须先跟Server端建立通信连接&#xff0c;而建立连接的工作就是由连接器完成的 mysql -h host[数据库地址] -u root[用户] -p root[密码] -P 3306连接步骤: 1、如果用户名或密码不对&#xff0c;你就会收到一个"Access denied for us…

学习阶段单片机买esp32还是stm32?

学习阶段单片机买esp32还是stm32? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「stm32的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xf…

爱心商城|爱心商城系统|基于Springboot的爱心商城系统设计与实现(源码+数据库+文档)

爱心商城系统目录 目录 基于Springboot的爱心商城系统设计与实现 一、前言 二、系统功能设计 三、系统功能设计 1、商品管理 2、捐赠管理 3、公告管理 4、公告类型管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#x…

SpringBoot+Vue全栈开发-刘老师教编程(b站)(二)

创建SpringBoot项目 1.配置maven 出现bug java: 无法访问org.springframework.boot.SpringApplication 错误的类文件: /D:/maven/repository/org/springframework/boot/spring-boot/3.0.0/spring-boot-3.0.0.jar!/org/springframework/boot/SpringApplication.class 类…

【力扣hot100】刷题笔记Day15

前言 今天要刷的是图论&#xff0c;还没学过&#xff0c;先看看《代码随想录》这部分的基础 深搜DFS理论基础 深搜三部曲 确认递归函数、参数确认终止条件处理目前搜索节点出发的路径 代码框架 void dfs(参数) {if (终止条件) {存放结果;return;}for (选择&#xff1a;本节点…

面试经典150题——最长连续序列

"The only limit to our realization of tomorrow will be our doubts of today." - Franklin D. Roosevelt ​ 1. 题目描述 2. 题目分析与解析 2.1 思路一 题目要求我们使用时间复杂度为O(n)的解决方案&#xff0c;那么肯定就不能排序了。因为排序算法不可能达到…

Java-nio

一、NIO三大组件 NIO的三大组件分别是Channel&#xff0c;Buffer与Selector Java NIO系统的核心在于&#xff1a;通道(Channel)和缓冲区(Buffer)。通道表示打开到 IO 设备(例如&#xff1a;文件、套接字)的连接。若需要使用 NIO 系统&#xff0c;需要获取用于连接 IO 设备的通…

打造去中心化透明储蓄罐:Solidity智能合约的又一实践

一、案例背景 传统的储蓄罐通常是由个人或家庭使用&#xff0c;用于存放硬币或小额纸币。然而&#xff0c;这样的储蓄罐缺乏透明性&#xff0c;用户无法实时了解储蓄情况&#xff0c;也无法确保资金的安全性。 通过Solidity智能合约&#xff0c;我们可以构建一个去中心化…

金三银四,自动化测试面试题精选【美团二面】

面试一般分为技术面和hr面&#xff0c;形式的话很少有群面&#xff0c;少部分企业可能会有一个交叉面&#xff0c;不过总的来说&#xff0c;技术面基本就是考察你的专业技术水平的&#xff0c;hr面的话主要是看这个人的综合素质以及家庭情况符不符合公司要求&#xff0c;一般来…

sawForceDimensionSDK安装,sigma7+ros

force dimension的sdk中没有关于ros&#xff0c;借助开源的sawForceDimensionSDK实现对于数据的封装和可视化&#xff0c;方便后续使用 链接&#xff1a; GitHub - jhu-saw/sawForceDimensionSDK 具体步骤&#xff1a; 安装qt和ros&#xff0c;官网下载Force Dimension SDK …

整合swagger,并通过Knife4j美化界面

如果是前后端分离的项目&#xff0c;需要前端的参与&#xff0c;所以一个好看的接口文档非常的重要 1、引入依赖 美化插件其中自带swagger的依赖了&#xff0c;所以不需要再单独导入swagger的坐标了 <dependency><groupId>com.github.xiaoymin</groupId>&…

免费音频剪辑

在数字时代&#xff0c;音频剪辑已成为许多职业和爱好者不可或缺的技能。无论是制作播客、教育视频、还是进行广告宣传&#xff0c;高质量的音频剪辑都能为作品增色不少。今天&#xff0c;我要为大家强烈安利一款免费且功能强大的音频剪辑工具&#xff0c;它绝对是你办公桌上不…
推荐文章