【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);//这里类型转换有点问题,因此我直接写8000watch->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.hqwc.cn/news/539248.html

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

相关文章

sqllab第十六关通关笔记

知识点&#xff1a; 布尔盲注时间盲注 布尔盲注 通过admin admin登录发现没有任何回显信息&#xff1b;但是使用的是成功登录的图片 随便输入一个用户和密码发现出现了错误登录的图片信息 构造usernamea# 感觉又是一个布尔注入 构造payload:usernameaor11# 发现登录失败的…

数据仓库为什么要分层建设?每一层的作用是什么?

在数字化时代&#xff0c;数据已成为企业最宝贵的资产之一。为了更好地管理和利用这些数据&#xff0c;许多企业都建立了数据仓库。然而&#xff0c;数据仓库并非简单的数据存储工具&#xff0c;而是一个复杂的数据处理和分析系统。其中&#xff0c;分层建设是数据仓库设计的重…

sqllab第二十关通关笔记

知识点&#xff1a; cookie注入 可以进行url解析错误注入传参位置 get请求post请求cookie传参 输入admin admin进行登录&#xff0c;抓取当前数据包 通过放包发现是一个302跳转的响应包&#xff0c;页面只有一个 I Love Cookies&#xff1b;没什么信息 通过点击页面上方的按钮…

SpringBoot异常:类文件具有错误的版本 61.0, 应为 52.0的解决办法

问题&#xff1a; java: 无法访问org.mybatis.spring.annotation.MapperScan 错误的类文件: /D:/Program Files/apache-maven-3.6.0/repository/org/mybatis/mybatis-spring/3.0.3/mybatis-spring-3.0.3.jar!/org/mybatis/spring/annotation/MapperScan.class 类文件具有错误的…

Redis 除了做缓存,还能做什么?

分布式锁&#xff1a;通过 Redis 来做分布式锁是一种比较常见的方式。通常情况下&#xff0c;我们都是基于 Redisson 来实现分布式锁。关于 Redis 实现分布式锁的详细介绍&#xff0c;可以看我写的这篇文章&#xff1a;分布式锁详解open in new window 。限流&#xff1a;一般是…

Grass推出Layer 2 Data Rollup

Grass推出Layer 2 Data Rollup Grass邀请链接最新资讯 Grass邀请链接 欢迎使用我的邀请码进行注册: 邀请链接 如果你还不知道注册流程&#xff1a;详见Grass: 出售闲置带宽实现被动收入 最新资讯 简讯&#xff1a;2024年3月13日&#xff0c;Grass宣布正在建立基于Solana的La…

基于单片机的车载酒精含量自检系统设计与实现

摘要:调查显示,大约50%的交通事故与酒后驾车有关,酒后驾车已成为车祸致死的首要原因。为从根本上杜绝酒后驾车,设计了一款基于STC89C52 单片机的车载酒精含量自检系统,该系统能很好地解决酒驾问题,控制简单、使用方便,具有很好的应用价值。 关键词:STC89C52 单片机;车…

牛牛的凑数游戏 --- 题解

目录 牛牛的凑数游戏&#xff1a; 题目大意&#xff1a; 思路解析&#xff1a; 代码实现&#xff1a; 牛牛的凑数游戏&#xff1a; 题目大意&#xff1a; 思路解析&#xff1a; 我们可以很容易一个区间是否会存在1&#xff0c;那么我们想如果存在1&#xff0c;且有3个1&…

电商场景下 ES 搜索引擎的稳定性治理实践

继上文在完成了第一阶段 ES 搜索引擎的搭建后&#xff0c;已经能够实现对千万级别的商品索引的读写请求的支持。目前&#xff0c;单机房读流量在 500&#xff5e;1000 QPS 之间&#xff0c;写流量在 500 QPS 左右。 但随着业务的发展&#xff0c;问题也逐渐开始暴露&#xff0…

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

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

[保姆级教程]Windows安装MongoDB教程

文章目录 导文MongoDB安装包下载1.点击进入mongodb官网2.点击MongoDB Community Edition&#xff08;社区版&#xff09;&#xff0c;进入下图界面3.选择版本4.下载5.安装6.勾选同意协议&#xff0c;点击“Next"7.选择自定义安装8.点击“Next"9.修改到合适的地址10.点…

3D全景:为各行业提供更真实的交互体验

近年来&#xff0c;随着科技的不断发展&#xff0c;3D全景技术逐渐融入到了我们的日常生活中来。3D全景技术的应用落地&#xff0c;为广大用户提供了全新的视觉体验&#xff0c;让人们能够更加真实、直观地感受各行业的场景。 3D全景的优势就在于真实感和互动性&#xff0c;可以…