【QT】TCP简易聊天框

news2024/12/27 1:08:59

在这里插入图片描述

我们首先复习一下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.coloradmin.cn/o/1517381.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

碳储量监测的新技术:遥感在草原碳汇评估中的潜力

在全球环境问题日益严重的今天&#xff0c;以全球变暖为主要特征的气候变化成为了人类面临的巨大挑战。它威胁着地球的生态平衡&#xff0c;对全球可持续发展构成了严峻的挑战。为了应对这一挑战&#xff0c;各国纷纷采取行动&#xff0c;致力于实现碳达峰和碳中和的目标。 在…

Zabbix 监控 tomcat

zabbix-java-gateway服务组件 zabbix监控tomcat需要用到zabbix-java-gateway组件&#xff0c;它充当zabbix服务和java应用程序之间的网关。它允许zabbix服务器用过java网关与java应用程序进行通信&#xff0c;从而监控和收集java应用程序的性能数据。 zabbix-agent服务&#xf…

gradio部署视频输入输出示例,gradio网页输出视频nan,输出视频无法播放解决方法

gradio部署视频输入输出示例&#xff0c;gradio网页输出视频nan&#xff0c;输出视频无法播放 Opencv不能采用h64格式进行编码解决方案moviepy介绍浏览器接受的视频编码格式&#xff1a;采用h264编码合成视频&#xff1a; gradio部署视频输入输出示例Gradio视频组件使用详解简介…

小程序学习3 goods-card

pages/home/home home.wxml <goods-listwr-class"goods-list-container"goodsList"{{goodsList}}"bind:click"goodListClickHandle"bind:addcart"goodListAddCartHandle"/> <goods-list>是一个自定义组件&#xff0c;它具…

【MIT 6.S081】2020, 实验记录(8),Lab: locks

目录 Task 1&#xff1a;Memory allocator (moderate)</font>Task 2&#xff1a;Buffer cache (hard)</font> Task 1&#xff1a;Memory allocator (moderate) 这个任务就是练习将一把大锁拆分为多个小锁&#xff0c;同时可以更加深入地理解 memory allocator 运行…

PY32离线烧录器功能介绍,可批量烧录,支持PY32系列多款单片机

PY32离线烧录器可以对PY系列单片机进行批量烧录&#xff0c;现支持PY32F002A/002B/002/003/030/071/072/040/403/303芯片各封装和XL2409&#xff0c;XL32F001/003等芯片。PY32离线烧录器需要搭配上位机软件才能使用&#xff0c;上位机软件在我们官网&#xff08;www.xinlinggo.…

JVM基础篇

什么是JVM java虚拟机 JVM的功能 1.解释和运行 对字节码文件中的指令&#xff0c;实时的解释成机器码&#xff0c;让计算机执行 2.内存管理 自动为对象、方法等分配内存 自动的垃圾回收机制&#xff0c;回收不再使用的对象&#xff08;c不会自动回收&#xff0c;相当于降…

QT 如何防止 QTextEdit 自动滚动到最下方

在往QTextEdit里面append字符串时&#xff0c;如果超出其高度&#xff0c;默认会自动滚动到QTextEdit最下方。但是有些场景可能想从文本最开始的地方展示&#xff0c;那么就需要禁止自动滚动。 我们可以在append之后&#xff0c;添加如下代码&#xff1a; //设置编辑框的光标位…

指针的函数传参的详细讲解(超详细)

如果对指针基础知识已经有可以直接跳到 函数的指针传参与解引用&#xff0c;哪里不明白可以评论&#xff0c;随时解答。 目录 所以就有了一句话&#xff1a;指针就是地址&#xff0c;地址就是指针 对于指针在C语言中&#xff0c;指针类型就是数据类型&#xff0c;是给编译器…

PHP极简网盘系统源码 轻量级文件管理与共享系统网站源码

PHP极简网盘系统源码 轻量级文件管理与共享系统网站源码 极简网盘是一个轻量级文件管理与共享系统&#xff0c;支持多用户&#xff0c;可充当网盘程序&#xff0c;程序无需数据库 安装步骤&#xff1a; 1.建议安装在apache环境下&#xff0c;并确保.htaccess可用 2.解压文件…

论文阅读——RingMo

RingMo: A Remote Sensing Foundation Model With Masked Image Modeling 与自然场景相比&#xff0c;RS图像存在以下困难。 1&#xff09;分辨率和方位范围大&#xff1a;受遥感传感器的影响&#xff0c;图像具有多种空间分辨率。此外&#xff0c;与自然图像的实例通常由于重…

【Python】Leetcode 240. 搜索二维矩阵 II - 削减矩阵+递归,击败88%

描述 搜索二维矩阵 II 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。 该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 思路 确定左右及上下限&#xff0c;削减矩阵&#xff0c;递归。 注意判断四个端…

15届蓝桥杯第一期模拟赛所有题目解析

文章目录 &#x1f9e1;&#x1f9e1;t1_字母数&#x1f9e1;&#x1f9e1;问题描述思路代码 &#x1f9e1;&#x1f9e1;t2_大乘积&#x1f9e1;&#x1f9e1;问题描述思路代码 &#x1f9e1;&#x1f9e1;t3_星期几&#x1f9e1;&#x1f9e1;问题描述思路代码 &#x1f9e1;…

Spring基础——使用注解开发SpringMVC

目录 配置SpringMVC的初始化信息配置ServletWebApplicationContext配置RootWebApplicationContext配置ServletContext 创建Controller控制器配置Controller响应路径接收用户传递参数接收JSON数据接收简单类型对象封装参数 接收数组类型 Restful 文章源码仓库&#xff1a;Spring…

大模型笔记:吴恩达 ChatGPT Prompt Engineering for Developers(1) prompt的基本原则和策略

1 intro 基础大模型 VS 用指令tune 过的大模型 基础大模型 只会对prompt的文本进行续写 所以当你向模型发问的时候&#xff0c;它往往会像复读机一样续写几个问题这是因为在它见过的语料库文本&#xff08;通常大多来自互联网&#xff09;中&#xff0c;通常会连续列举出N个问…

Flask vs. Django:选择适合你的Web开发框架【第134篇—Flask vs. Django】

Flask vs. Django&#xff1a;选择适合你的Web开发框架 在选择一个适合你项目的Web开发框架时&#xff0c;常常会遇到 Flask 和 Django 这两个流行的选择。两者都有其优势和适用场景&#xff0c;本文将探讨它们的特点&#xff0c;并通过代码实例和解析来帮助你更好地做出选择。…

环形链表的起点——细节讲解

对于一个环形链表&#xff0c;我们要找到他的起点。可以通过如下推导。 我们设置两个快慢指针&#xff0c;相遇的点为X. 到起点的距离是T&#xff0c;圈长是C&#xff0c;第一次相交的点是X &#xff08;TX&#xff09;2TNCX 化出来TN*C-X 也就是说我们把一个节点放头部重新遍…

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

快速前往文章列表&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;五&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;七&#xff09; 19. sqlite3_changes与sqlite3_changes64 是SQLite中用…

手机安装Kali Linux

在数字化时代&#xff0c;信息安全和隐私保护显得尤为重要。Kali Linux&#xff0c;作为一款专业的渗透测试和安全审计工具&#xff0c;因其强大的功能和丰富的资源库而受到广大安全研究者和爱好者的青睐。然而&#xff0c;我们通常只能在传统的电脑设备上安装和使用Kali Linux…

外卖小程序-购物车模块表结构设计和后端代码

表结构设计 添加购物车代码 Service public class ShoppingCartServiceImpl implements ShoppingCartService {Autowiredprivate ShoppingCartMapper shoppingCartMapper;Autowiredprivate DishMapper dishMapper;Autowiredprivate SetmealMapper setmealMapper;/*** 添加购物…