当前位置: 首页 > news >正文

QT中的TCP

QT中的TCP

回显服务器

  1. 创建界⾯. 包含⼀个 QListWidget , ⽤于显⽰收到的数据.

  2. 创建 QTcpServer 并初始化

修改 widget.h, 添加 QTcpServer 指针成员.

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void processConnection();QString process(const QString request);
private:Ui::Widget *ui;QTcpServer *tcpServer;
};
#endif // WIDGET_H

修改 widget.cpp, 实例化 QTcpServer 并进⾏后续初始化操作.

• 设置窗⼝标题

• 实例化 TCP server. (⽗元素设为当前控件, 会在⽗元素销毁时被⼀起销毁).

• 通过信号槽, 处理客⼾端建⽴的新连接.

• 监听端⼝

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//1.修改窗口标题this->setWindowTitle("服务器");//2.创建TcpServer的实例tcpServer=new QTcpServer(this);//3.通过信号槽,指定如何处理connect(tcpServer,&QTcpServer::newConnection,this,&Widget::processConnection);//4.绑定监听端口号bool ret=tcpServer->listen(QHostAddress::Any,9090);if(!ret){QMessageBox::critical(this,"服务器启动失败",tcpServer->errorString());exit(1);}
}
  1. 继续修改 widget.cpp, 实现处理连接的具体⽅法 processConnection

• 获取到新的连接对应的 socket.

• 通过信号槽, 处理收到请求的情况

• 通过信号槽, 处理断开连接的情况

Widget::~Widget()
{delete ui;
}void Widget::processConnection()
{QTcpSocket* clientSocket=tcpServer->nextPendingConnection();QString log="["+clientSocket->peerAddress().toString()+":"+QString::number(clientSocket->peerPort())+"]客户端上线";ui->listWidget->addItem(log);connect(clientSocket,&QTcpSocket::readyRead,this,[=](){QString request=clientSocket->readAll();const QString& response=process(request);clientSocket->write(response.toUtf8());QString log = QString("[") + clientSocket->peerAddress().toString()+ ":" + QString::number(clientSocket->peerPort()) + "] 客⼾端下线!";ui->listWidget->addItem(log);clientSocket->deleteLater();});
}
  1. 实现 process ⽅法, 实现根据请求处理响应.

由于我们此处是实现回显服务器. 所以 process ⽅法中并没有包含实质性的内容.

QString Widget::process(const QString request)
{return request;
}

💡 “根据请求处理响应” 是服务器开发中的最核⼼的步骤.

⼀个商业服务器程序, 这⾥的逻辑可能是⼏万⾏⼏⼗万⾏代码量级的.

此时, 服务器程序编写完毕.

但是直接运⾏还看不出效果. 还需要搭配客⼾端来使⽤

回显客⼾端

  1. 创建界⾯. 包含⼀个 QLineEdit , QPushButton , QListWidget

• 先使⽤⽔平布局把 QLineEdit 和 QPushButton 放好, 并设置这两个控件的垂直⽅向的sizePolicy 为 Expanding

• 再使⽤垂直布局把 QListWidget 和上⾯的⽔平布局放好.

• 设置垂直布局的 layoutStretch 为 5, 1 (当然这个尺⼨⽐例根据个⼈喜好微调).

  1. 创建 QTcpSocket 并实例化

修改 widget.h, 创建成员.

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_clicked();private:Ui::Widget *ui;QTcpSocket*socket;
};
#endif // WIDGET_H

修改 widget.cpp, 对 QTcpSocket 进⾏实例化.

• 设置窗⼝标题

• 实例化 socket 对象 (⽗元素设为当前控件, 会在⽗元素销毁时被⼀起销毁).

• 和服务器建⽴连接.

• 等待并确认连接是否出错

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//1.设置窗口标题this->setWindowTitle("客户端");//2.创建socket对象实例socket=new QTcpSocket(this);//3.和服务器建立连接socket->connectToHost("127.0.0.1",9090);//4.连接信号槽connect(socket,&QTcpSocket::readyRead,this,[=](){//a)读取响应内容QString response=socket->readAll();//b)把相应内容显示到界面上ui->listWidget->addItem("服务器说:"+response);});//5.等待连接的结果,确认是否成功bool ret=socket->waitForConnected();if(!ret){QMessageBox::critical(this,"服务器连接错误",socket->errorString());exit(1);}
}
  1. 修改 widget.cpp, 给按钮增加点击的 slot 函数, 实现发送请求给服务器
void Widget::on_pushButton_clicked()
{//1.获取到输入框中的内容const QString& text=ui->lineEdit->text();//2.发送数据到服务器socket->write(text.toUtf8());//3.把发的消息显示到界面上ui->listWidget->addItem("客户端说:"+text);//4.清空输入框的内容ui->lineEdit->setText("");
}
  1. 修改 widget.cpp 中的 Widget 构造函数, 通过信号槽, 处理收到的服务器的响应.
connect(socket,&QTcpSocket::readyRead,this,[=](){//a)读取响应内容QString response=socket->readAll();//b)把相应内容显示到界面上ui->listWidget->addItem("服务器说:"+response);});

的服务器的响应.

connect(socket,&QTcpSocket::readyRead,this,[=](){//a)读取响应内容QString response=socket->readAll();//b)把相应内容显示到界面上ui->listWidget->addItem("服务器说:"+response);});
http://www.dtcms.com/a/360985.html

相关文章:

  • 摄像头模块的电子集成设计
  • 开发使用mybatis是用混合模式还是全注解模式
  • pprint:美观打印数据结构
  • Spring Boot 和 Spring Cloud 的原理和区别
  • Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
  • 单例模式
  • Day19_【机器学习—线性回归 (3)—回归模型评估方法】
  • 网站模板源代码 静态网页网站模板
  • VBA数据库解决方案第二十二讲:根据工作表数据生成数据库中数据表
  • 零售行业的 AI 革命:从用户画像到智能供应链,如何让 “精准营销” 不再是口号?
  • 百胜软件获邀出席第七届中国智慧零售大会,智能中台助力品牌零售数智变革
  • 百胜软件×OceanBase深度合作,赋能品牌零售数字化实践降本增效
  • leetcode 面试题17.19 消失的两个数字
  • Java学习笔记-反射(二)
  • 无公网IP,怎么实现远程调试与APP端api 接入?
  • 红楼梦 AI HTML 分析 - 好了歌
  • MySQL内置的各种单行函数
  • Kafka消息中间件安装配置
  • Ruoyi项目MyBatis升级MyBatis-Plus指南
  • sentinel异常处理机制
  • 2025机器人产业大洗牌:新兴初创企业的技术革命与崛起之路
  • 【Spring Cloud微服务】8.深度实战:微服务稳定性的守护神——Sentinel
  • Linux下usb设备驱动框架实现:定义核心结构体数据
  • 从Java全栈开发到微服务架构:一次真实的面试实录
  • leetcode算法刷题的第二十三天
  • GitLab 18.3 正式发布,更新多项 DevOps、CI/CD 功能【一】
  • Linux上perf工具的使用-基础采样
  • 云端虚拟云手机该如何进行使用?
  • 高并发场景下的热点数据处理:从预热到多级缓存的性能优化实践
  • 云手机和云游戏之间有着哪些区别?