【QT】TCP简易聊天框

在这里插入图片描述

我们首先复习一下TCP通信的流程

基于linuxTCP客户端和服务器

QT下的TCP处理流程

服务器先启动(处于监听状态)

在这里插入图片描述

各函数的意义和使用

  • QTcpServer Class

    *QTcpServer*类提供了一个基于TCP的服务器。这个类可以接受传入的TCP连接。您可以指定端口或让QTcpServer自动选择一个端口。您可以收听特定地址或所有机器的地址。调用listen()让服务器侦听传入的连接。每次客户端连接到服务器时,都会发出newConnection()信号。

  • QTcpSocket Class

    QTcpSocket类提供了一个TCP套接字。TCP(传输控制协议)是一种可靠的,面向流的,面向连接的传输协议。 它特别适合连续传输数据。QTcpSocketQAbstractSocket的一个方便的子类,它允许你建立一个TCP连接并传输数据流。

    • 服务器端以监听的方式监听listen()客户端是否有连接请求
    • 客户端以调用**connectToHost()**函数主动连接服务器端
  • listen():Qt中,服务端的监听套接字不再是socket,而是QTcpServerQTcpSocket。此外,它将绑定bind()和监听listen()合为一个函数,即监听listen(),在调用的同时指定主机地址和端口号。

  • connectToHost()【客户端】
    而客户端的通信套接字也不再是socket,而是QTcpSocket,连接也不是connect(),而是connectToHost(),意为主动向主机(服务端)发起连接。

  • newConnection()【服务端】
    如果客户端发起连接并且成功,服务端将会收到一个信号。在Qt中,服务端不再是由accept()来确定连接的建立,而是会触发一个newConnection信号。既然是信号,就要有与之对应的槽函数。槽函数中主要的工作是取出建立好的套接字QTcpSocket(它是真正的通信套接字)。

  • write()【服务端/客户端】
    客户端用write()发送数据,如果数据传送成功,对方的通信套接字会触发readyRead()信号(继承自QIODevice类的信号),说明可以开始读数据了,我们需要在对应的槽函数中做接收处理。反过来,服务端给客户端发信息也是一样的。

  • connected() & disconnected()【服务端/客户端】
    只要成功与对方建立连接,无论是服务端还是客户端,通信套接字都会自动触发

  • **connected()**信号,而如果对方主动断开连接,通信套接字会自动触发disconnected()信号,我们可以利用这两个信号作出一些提示,比如在客户端与服务器端成功连接后,在客户端窗口输出“已成功连接服务器!”或者“已与服务器断开连接!”。

添加TCP模块

在这里插入图片描述

#include <QTcpServer>
#include <QTcpSocket>

在这里插入图片描述

## client.ui

client.h/server.h


#include <QTcpSocket>
...
class Client : public QWidget
{
  ...
private:
    Ui::Client *ui;
  QTcpSocket *client_chat;
 
  -------------------------------------

#include <QTcpSocket>
#include <QTcpServer>
#include <QPushButton>
....
class Server : public QWidget
{
  ....
private:
    Ui::Server *ui;
     QTcpServer *watch;//监听
    QTcpSocket *chat;  //通信
};

#endif // SERVER_H

client.cpp

#include "client.h"
#include "ui_client.h"
#include <QTcpSocket>
#include <QHostAddress>
#include <QDebug>
Client::Client(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Client)
{
    ui->setupUi(this);

    ui->sIP->setText("127.0.0.1");
    ui->sPort->setText("8000");

    client_chat = new QTcpSocket(this);
    client_chat->connectToHost(QHostAddress(ui->sIP->text()),8000);
    connect(client_chat,&QTcpSocket::readyRead,this,[=](){

        qDebug()<<1;
        QByteArray qba2 = client_chat->readAll();
        ui->record->append("对方说"+qba2);

    });

    connect(ui->send,&QPushButton::clicked,this,[=](){
       client_chat->write(ui->input->toPlainText().toUtf8());

       ui->record->append("Me say:"+ui->input->toPlainText());
       ui->input->clear();
    });
}

server.cpp

#include "server.h"
#include "ui_server.h"
#include <QDebug>
Server::Server(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Server)
{
    ui->setupUi(this);
    ui->sIP->setText("127.0.0.1");
    ui->sPort->setText("8000");

    watch = new QTcpServer(this);
                                //这里类型转换有点问题,因此我直接写8000
    watch->listen(QHostAddress(ui->sIP->text()),8000);

    connect(watch,&QTcpServer::newConnection,this,[=](){
       chat = watch->nextPendingConnection();
       ui->record->append("有新的连接");

       QList<QTcpSocket*>socketList;
       socketList.append(chat);
       QString IP= chat->peerAddress().toString();
       quint16 PORT = chat->peerPort();

       qDebug()<<socketList;
       qDebug()<<IP<<PORT;

       connect(chat,&QTcpSocket::readyRead,this,[=](){
          QByteArray qba = chat->readAll();
          ui->record->append("对方说:"+qba);
       });
    });

    connect(ui->send,&QPushButton::clicked,this,[=](){
       chat->write(ui->input->toPlainText().toUtf8());
      ui->record->append("MeSay:"+ui->input->toPlainText());

      ui->input->clear();

    });
}

main.c

#include "server.h"
#include "client.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Server w;
    w.show();

    Client c;
    c.setWindowTitle("客户端");
    c.show();
    return a.exec();
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决无法登录到 ArcGIS Server Administrator

目录 问题复现原因分析解决办法 问题复现 今天在访问arcgisserver后台准备设置arcgis api for js请求路径时&#xff0c;登录之后出现500错误。Services Directoryhttp://xxx.xxx.xxx.xxx:6080/arcgis/admin/system/handlers/rest/servicesdirectory 原因分析 我实在两台虚拟机…

信号与系统学习笔记——信号的分类

目录 一、确定与随机 二、连续与离散 三、周期与非周期 判断是否为周期函数 离散信号的周期 结论 四、能量与功率 定义 结论 五、因果与反因果 六、阶跃函数 定义 性质 七、冲激函数 定义 重要关系 作用 一、确定与随机 确定信号&#xff1a;可以确定时间函数…

提升运营效率,探索运营中台架构的力量

随着数字化转型的加速推进&#xff0c;企业需要更高效地管理和运营各项业务&#xff0c;而运营中台架构作为一种新型的业务架构设计理念&#xff0c;正在逐渐受到关注和应用。本篇博客将深入探讨运营中台架构的概念、优势和实践&#xff0c;帮助企业了解如何通过构建运营中台实…

CVPR2023 | 3D Data Augmentation for Driving Scenes on Camera

3D Data Augmentation for Driving Scenes on Camera 摄像机驾驶场景的 3D 数据增强 摘要翻译 驾驶场景极其多样和复杂&#xff0c;仅靠人力不可能收集到所有情况。虽然数据扩增是丰富训练数据的有效技术&#xff0c;但自动驾驶应用中现有的摄像头数据扩增方法仅限于二维图像…

[蓝桥杯]-最大的通过数-CPP-二分查找、前缀和

目录 一、题目描述&#xff1a; 二、整体思路&#xff1a; 三、代码&#xff1a; 一、题目描述&#xff1a; 二、整体思路&#xff1a; 首先要知道不是他们同时选择序号一样的关卡通关&#xff0c;而是两人同时进行两个入口闯关。就是说两条通道存在相同关卡编号的的关卡被通…

PlantUML Integration 编写短信服务类图

PlantUML Integration 写一个类图&#xff0c;主要功能为 1、编写一个serviceSms短信服务类&#xff1b; 2、需要用到短信的地方统一调用基建层的服务即可&#xff1b; 3、可以随意切换、增加短信厂商&#xff0c;不需要更改场景代码&#xff0c;只需要更改application.yml 里面…

SQLiteC/C++接口详细介绍之sqlite3类(七)

上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;六&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍之sqlite3类&#xff08;八&#xff09;&#xff08;未发表&#xff09; 22.sqlite3_create_collation、sqlite3_create_collation16和sqlite3_creat…

JavaEE--小Demo

目录 下载包 配置 修改文件 pom.xml application.properties 创建文件 HelloApi.java GreetingController.java Greeting.java DemoApplication.java 运行包 运行命令 mvn package cd target dir java -jar demo-0.0.1-SNAPSHOT.jar 浏览器测试结果 下载包 …

网络安全专题第一篇:网络安全的来源

目录 一.网络安全的由来。 二.网络安全漏洞在哪里 三.网络安全规范操作 1.从业务入手 2.从安全体系入手 3.从管理入手 四.可能遇到的网络攻击 1.DDOS 2.勒索攻击 3.单包攻击 4.员工删库跑路 5.熊猫烧香 五.应对方法 1.清洗 2.提高服务器的承受能力 3.防火墙 4…

证券公司如何应对大数据调度系统的高负载挑战

​在金融行业&#xff0c;数据处理和任务调度是日常运营的重要组成部分。随着业务量的激增&#xff0c;日益增长的任务量和复杂的资源管理需求&#xff0c;要求该系统不仅要稳如磐石&#xff0c;还需灵活高效。 本文将探讨某证券公司在应对这些挑战时所采用的策略&#xff0c;并…

tomcat的webapp文件中发布web应用

一、Web服务器 1.什么是Web 概述&#xff1a; web(World Wide Web)即全球广域网&#xff0c;也称为万维网&#xff0c;它是一种基于超文本和HTTP的、全球性的、动态交百的、跨平台的分布式图形信息系统。是建立在internet上的一种网络服务&#xff0c;为浏览者在Intern…

笔记80:在 Ubuntu 中安装显卡驱动

一、关于显卡的两个基本概念 -- 显卡驱动 / 显卡BIOS &#xff08;1&#xff09;什么是BIOS BIOS的作用&#xff1a;BIOS是电脑上电开机时加载进内存的第一个程序&#xff0c;CPU会执行他进行系统自检&#xff0c;然后通过其中的指令加载操作系统&#xff1b;例如主板BIOS&am…

react 项目如何暴露 webpack配置文件

首先创建一个项目&#xff1a; // 全局安装 create-react-app 脚手架 npm install create-react-app -g// 创建项目 create-react-app demo 创建完成后&#xff0c;进到项目根目录&#xff0c;执行以下命令&#xff1a; npm run eject 出现以下命令&#xff1a; 选择yes即可…

【Unity】Transform、Rigidbody、CharacterController移动

前言 在使用Unity开发的时候&#xff0c;移动是最最基础的一个需求&#xff0c;我来给大家简单的讲一下Unity中的几种常见的移动方法。 1.Transform移动 Transform移动就是修改物体的position ①修改位置 这里要注意&#xff1a;坐标分为世界坐标和本地坐标 //将物体的世界坐…

import gdal 报错

1.下载gdal https://www.lfd.uci.edu/~gohlke/pythonlibs/#gdal 2.安装正确版本 &#xff08;1&#xff09;查看python版本 python -v我的版本Python 3.7.9 建议下载 GDAL-3.4.2-cp37-cp37m-win_amd64.whl &#xff08;2&#xff09;放到Scripts文件夹下 执行 pip install GD…

Unity Timeline学习笔记(2) - PlayableTrack

PlayableTrack 是可自定义播放的轨道。我们可以通过进入轨道后调用自己的函数方法&#xff0c;使用起来也是比较顺手的。 添加轨道 我们点击加号添加 这样就有一个空轨道了&#xff0c;然后我们创建两个测试脚本。 添加脚本 分别是Playable Behaviour和PlayableAsset脚本。…

吴恩达深度学习笔记:神经网络的编程基础2.9-2.14

目录 第一门课&#xff1a;神经网络和深度学习 (Neural Networks and Deep Learning)第二周&#xff1a;神经网络的编程基础 (Basics of Neural Network programming)2.9 逻辑回归中的梯度下降&#xff08;Logistic Regression Gradient Descent&#xff09; 第一门课&#xff…

vue 基于elementUI/antd-vue, h函数实现message中嵌套链接跳转到指定路由 (h函数点击事件的写法)

效果如图&#xff1a; 点击message 组件中的 工单管理&#xff0c; 跳转到工单管理页面。 以下是基于vue3 antd-vue 代码如下&#xff1a; import { message } from ant-design-vue; import { h, reactive, ref, watch } from vue; import { useRouter } from vue-router; c…

蓝桥杯单片机快速开发笔记——定时器

一、基本原理&#xff1a; 定时器的作用&#xff1a; 定时器是一种用于产生精确时间延时的模块&#xff0c;可以在程序中用来进行时间控制、计时等操作。 定时器的工作原理&#xff1a; 51单片机的定时器是通过内部的计数器来实现的&#xff0c;计数器每隔一个固定的时间周期自…

C#,数值计算,矩阵相乘的斯特拉森(Strassen’s Matrix Multiplication)分治算法与源代码

Volker Strassen 1 矩阵乘法 矩阵乘法是机器学习中最基本的运算之一,对其进行优化是多种优化的关键。通常,将两个大小为N X N的矩阵相乘需要N^3次运算。从那以后,我们在更好、更聪明的矩阵乘法算法方面取得了长足的进步。沃尔克斯特拉森于1969年首次发表了他的算法。这是第…