QT实现TCP服务器客户端的实现

ser:

widget.cpp:

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//实例化一个服务器server = new QTcpServer(this);// 此时,服务器已经成功进入监听状态,如果有客户端向服务器发来连接请求//那么该服务器,就会自动发射一个newConnection的信号,我们可以将该信号连接到对应槽函数中执行相关逻辑//由于只需要连接一次即可,所以可以将该连接放在构造函数中完成connect(server, &QTcpServer::newConnection, this, &Widget::newConnection_slot);}Widget::~Widget()
{delete ui;
}//启动服务器按钮对应的槽函数
void Widget::on_startBtn_clicked()
{quint16 port = ui->lineEdit->text().toUInt();//监听客户端的连接请求//函数原型: bool listen(const QHostAddress &address = QHostAddress::Any,quint16 port = 0);//参数1:要监听的主机地址,如果是any表示监听任意一个主机地址,也可以是特定的主机地址//参数2:该服务器提供的端口号如果是0,表示有服务器指定,一般由程序员指定//返回值:成功进入坚挺状态,返回true,其他情况返回falseif(!server->listen(QHostAddress::Any, port)){QMessageBox::information(this, "失败", "监听失败");}else{QMessageBox::information(this, "成功", "监听成功");}
}//自定义处理newConnection信号的槽函数的实现
void Widget::newConnection_slot()
{qDebug()<<"您有新的客户端发来连接请求";//获取最新链接的客户端套接字//函数原型:virtual QTcpsocket *nextPendingconnection() ;//参数:无//返回值:最新连接过来的客户端套接字的地址QTcpSocket *s = server->nextPendingConnection();//将该套接字放入客户端链表中clientList.push_back(s);//至此,多个客户端已经跟付曲奇建立连接,并放入客户端容器中//此时。如果有客户端向服务器发来数据,那么对应的客户端套接字就会自动发射一个readyRead信号//我们可以将该信号连接到自定义的槽函数中,处理相关逻辑connect(s, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);}
//readyRead对应槽函数的实现
void Widget::readyRead_slot()
{qDebug()<<"有新消息来咯";//遍历客户端链表,将无效的客户端移除for(int i=0;i<clientList.size();i++){//判断当前套接字是否是有效连接//函数原型:Socketstate state() const;//参数:无//返回值:套接字的状态,如果是0,表示该套接字无效if(clientList[i]->state() == 0){//将该套接字移除客户端容器clientList.removeAt(i);}}//遍历客户端链表,判断是哪个客户端发来数据for (int i=0;i<clientList.size();i++){//函数原型 :qint64 bytesAvailable() const override;//求当前哭护短套接字中歹毒数据的字节数//参数:无//返回值:待读数据的字节数,如果是0,表示无数据待读if(clientList[i]->bytesAvailable() != 0){//将改套接字的数据读出来QByteArray msg = clientList[i]->readAll();//将数据展示到ui界面ui->listWidget->addItem(QString::fromLocal8Bit(msg));//将接收到的数据转发给所有客户端for (int j=0;j<clientList.size();j++){clientList[j]->write(msg);}}}}

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QTcpServer>            //服务器头文件
#include<QTcpSocket>             //客户端头文件
#include<QList>                  //链表容器
#include<QMessageBox>            //消息对话框
#include<QDebug>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_startBtn_clicked();void newConnection_slot();          //自定义处理newConnection信号的槽函数的声明void readyRead_slot();              //自定义处理readyRead信号的槽函数的声明private:Ui::Widget *ui;//定义服务器指针QTcpServer *server;//定义客户端容器QList<QTcpSocket *> clientList;};
#endif // WIDGET_H

widget.ui

cli:

widget.cpp

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//给客户端指针实例化对象socket = new QTcpSocket(this);//此时,已经向服务器发送连接请求了,如果成功连接服务器,那么该客户端就会自动发射一个connected的信号//我们可以将该信号连接到自定义的槽函数中处理逻辑//由于只需要连接一次,所以将连接写在构造函数中connect(socket, &QTcpSocket::connected, this, &Widget::connected_slot);//如果服务器向客户端发来消息,那么该客户端就会自动发射一个readyRead信号//我们可以将该进行连接到自定义的槽函数中处理相关逻辑connect(socket, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);//当成功与服务器断开连接后,该客户端会自动发射一个disconnected的信号//我们可以将该信号连接到自定义的槽函数中处理相关逻辑//由于该连接只需连接一次即可,所以放在构造函数中进行connect(socket, &QTcpSocket::disconnected, this, &Widget::disconnected_slot);}Widget::~Widget()
{delete ui;
}//连接服务器按钮对应的槽函数
void Widget::on_connectBtn_clicked()
{//获取ui界面上的相关信息userName = ui->uernameEdit->text();         //获取用户名QString ip = ui->ipEdit->text();            //主机地址quint16 port = ui->portEdit->text().toUInt();        //端口号//函数原型:virtual void connectToHost(const QHostAddress &address, quint16 port);//功能:将客户端连接到给定的服务器//参数1:服务器的主机地址//参数2:端口号//返回值:无socket->connectToHost(ip, port);//此时,已经向服务器发送连接请求了,如果成功连接服务器,那么该客户端就会自动发射一个connected的信号//我们可以将该信号连接到自定义的槽函数中处理逻辑//由于只需要连接一次,所以将连接写在构造函数中}//处理connected信号的槽函数的定义
void Widget::connected_slot()
{QMessageBox::information(this, "成功", "您已经成功进入聊天室");//向服务器发送一条数据:***:进入聊天室QString msg = userName +": 进入聊天室";socket->write(msg.toLocal8Bit());          //将数据写给服务器
}//处理readyRead信号的槽函数的定义
void Widget::readyRead_slot()
{//读取套接字中的信息QByteArray msg = socket->readAll();//将数据展示到ui界面ui->msgWidget->addItem(QString::fromLocal8Bit(msg));
}//发送按钮对应的槽函数
void Widget::on_sendBtn_clicked()
{//获取ui界面输入的内容QString msg =userName+ ": " + ui->msgEdit->text();//发送给服务器socket->write(msg.toLocal8Bit());//清空编辑框内容ui->msgEdit->clear();
}//断开服务器按钮对应的槽函数
void Widget::on_disconnectBtn_clicked()
{//告诉大家我走了QString msg = userName +": 离开聊天室";socket->write(msg.toLocal8Bit());//断开连接//函数原型: virtual void disconnectFromHost();socket->disconnectFromHost();//当成功与服务器断开连接后,该客户端会自动发射一个disconnected的信号//我们可以将该信号连接到自定义的槽函数中处理相关逻辑//由于该连接只需连接一次即可,所以放在构造函数中进行
}//disconnected信号对应槽函数的定义
void Widget::disconnected_slot()
{QMessageBox::information(this, "提示", "退出成功");
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpSocket>
#include <QMessageBox>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_connectBtn_clicked();void connected_slot();void readyRead_slot();void on_sendBtn_clicked();void on_disconnectBtn_clicked();void disconnected_slot();private:Ui::Widget *ui;QTcpSocket *socket;QString userName;
};
#endif // WIDGET_H

widget.ui:

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

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

相关文章

嵌入式软件架构中抽象层设计方法

大家好&#xff0c;今天分享一篇嵌入式软件架构设计相关的文章。 软件架构这东西&#xff0c;众说纷纭&#xff0c;各有观点。什么是软件架构&#xff0c;我们能在网上找到无数种定义。 比如&#xff0c;我们可以这样定义&#xff1a;软件架构是软件系统的基本结构&#xff0c…

g(x)=abx形式的函数最小二乘法计算方法

设函数&#xff0c;利用最小二乘法求解系数a和b: 设&#xff0c;&#xff0c;有 用最小二乘法求解和后&#xff0c;可得和&#xff1a; &#xff0c;

【网络安全---ICMP报文分析】Wireshark教程----Wireshark 分析ICMP报文数据试验

一&#xff0c;试验环境搭建 1-1 试验环境示例图 1-2 环境准备 两台kali主机&#xff08;虚拟机&#xff09; kali2022 192.168.220.129/24 kali2022 192.168.220.3/27 1-2-1 网关配置&#xff1a; 编辑-------- 虚拟网路编辑器 更改设置进来以后 &#xff0c;先选择N…

用pyinstaller打包LGBM模型为ELF/EXE可执行文件

1. 引入 写好的python代码和模型&#xff0c;如果需要做到离线部署、运行&#xff0c;就必须要将代码和模型打包为可独立运行的可执行文件。 使用pyinstaller就能做到这个&#xff0c;相同的代码&#xff0c;在windows上运行就能打包为exe&#xff0c;在linux上运行就能打包为…

android studio导入android源码模块开发总结

一、aidegen自动生成并导入android模块 1.源码下载后&#xff0c;键入 . build/envsetup.sh lunch sdk_car_x86_64-userdebug 以上命令执行后&#xff0c;tools/asuite/aidegen的源码会被编译为aidegen可执行文件 2.使用aidegen生成并自动导入模块 aidegen Settings -i j -…

AJAX和JSON

1、AJAX&#xff1a; AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;是一种用于创建交互式、动态网页的技术。它允许网页在不重新加载整个页面的情况下与服务器进行异步通信&#xff0c;从而改善用户体验。以下是关于AJAX的一些重要信息&#xff1a; 异步通信&a…

银行业务队列简单模拟(队列应用)

设某银行有A、B两个业务窗口&#xff0c;且处理业务的速度不一样&#xff0c;其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时&#xff0c;B窗口处理完1个顾客。给定到达银行的顾客序列&#xff0c;请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时…

虚拟货币(也称为加密货币或数字货币)的运作

虚拟币发展史 虚拟币的发展史可以追溯到20世纪末和21世纪初&#xff0c;以下是虚拟币的重要发展节点&#xff1a; 1998年&#xff1a;比特币白皮书的发布 比特币的概念最早由中本聪&#xff08;Satoshi Nakamoto&#xff09;在1998年提出&#xff0c;随后在2008年发布了一份名…

(Note)机器学习面试题

机器学习 1.两位同事从上海出发前往深圳出差&#xff0c;他们在不同时间出发&#xff0c;搭乘的交通工具也不同&#xff0c;能准确描述两者“上海到深圳”距离差别的是&#xff1a; A.欧式距离 B.余弦距离 C.曼哈顿距离 D.切比雪夫距离 S:D 1. 欧几里得距离 计算公式&#x…

JavaScript事件之拖拽事件(详解)

在网页开发的过程中我们经常会接触到拖拽事件&#xff0c;虽然每个网页和每个网页的拖拽的效果大相径庭&#xff0c;但是从根本来讲&#xff0c;代码是几乎一模一样的。   简而言之&#xff0c;拖拽效果就是鼠标按下&#xff0c;被拖拽的元素随着鼠标而移动&#xff0c;鼠标松…

【单片机】13-实时时钟DS1302

1.RTC的简介 1.什么是实时时钟&#xff08;RTC&#xff09; &#xff08;rtc for real time clock) &#xff08;1&#xff09;时间点和时间段的概念区分 &#xff08;2&#xff09;单片机为什么需要时间点【一定的时间点干什么事情】 &#xff08;3&#xff09;RTC如何存在于…

Trie字符串统计(c++题解)

维护一个字符串集合&#xff0c;支持两种操作&#xff1a; I x 向集合中插入一个字符串 x&#xff1b;Q x 询问一个字符串在集合中出现了多少次。 共有 N 个操作&#xff0c;所有输入的字符串总长度不超过 105&#xff0c;字符串仅包含小写英文字母。 输入格式 第一行包含整…

Mydb数据库问题

1、请简要介绍一下这个基于 Java 的简易数据库管理系统。它的主要功能是什么&#xff1f; TM&#xff08;Transaction Manager&#xff09;&#xff1a;事务管理器&#xff0c;用于维护事务的状态&#xff0c;并提供接口供其他模块查询某个事务的状态。DM&#xff08;Data Man…

国庆假期day5

作业&#xff1a;请写出七层模型及每一层的功能&#xff0c;请绘制三次握手四次挥手的流程图 1.OSI七层模型&#xff1a; 应用层--------提供函 表示层--------表密缩 会话层--------会话 传输层--------进程的接收和发送 网络层--------寻主机 数据链路层----相邻节点的可靠传…

CAcUiDockControlBar初始位置 2023/8/19 下午3:51:18

2023/8/19 下午3:51:18 CAcUiDockControlBar初始位置 2023/8/19 下午3:52:00 CAcUiDockControlBar的初始位置是根据其在程序代码中的设置而确定的。通常情况下,它的初始位置可以通过以下几种方式进行设置: 使用Create函数:在创建CAcUiDockControlBar对象时,可以调用Cre…

2023/8/12 下午8:41:46 树状控件guilite

2023/8/12 下午8:41:46 树状控件guilite 2023/8/12 下午8:42:08 树状控件(Tree View)是一种常见的图形用户界面(GUI)元素,它通常用于显示层次结构数据或文件系统的目录结构。Guilite 是一个轻量级的跨平台 GUI 库,支持多种控件,包括树状控件。 在 Guilite 中使用树状…

Ubuntu22.04 交叉编译gcc9.5 for arm

一、准备 环境&#xff1a;ubuntu22.04为刚刚安装&#xff0c;未安装gcc等包 vi ~/.bashrc输入 export PATH$PATH:/opt/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin 保存,reboot 安装&#xff1a; sudo apt install cmake sudo apt install gawk sudo apt instal…

[BJDCTF2020]Mark loves cat

先用dirsearch扫一下&#xff0c;访问一下没有什么 需要设置线程 dirsearch -u http://8996e81f-a75c-4180-b0ad-226d97ba61b2.node4.buuoj.cn:81/ --timeout2 -t 1 -x 400,403,404,500,503,429使用githack python2 GitHack.py http://8996e81f-a75c-4180-b0ad-226d97ba61b2.…

详解Linux的系统调用fork()函数

在Linux系统中&#xff0c;fork()是一个非常重要的系统调用&#xff0c;它的作用是创建一个新的进程。具体来说&#xff0c;fork()函数会在当前进程的地址空间中复制一份子进程&#xff0c;并且这个子进程几乎完全与父进程相同&#xff0c;包括进程代码、数据、堆栈以及打开的文…

【Java 进阶篇】JDBC 数据库连接池详解

数据库连接池是数据库连接的管理和复用工具&#xff0c;它可以有效地降低数据库连接和断开连接的开销&#xff0c;提高了数据库访问的性能和效率。在 Java 中&#xff0c;JDBC 数据库连接池是一个常见的实现方式&#xff0c;本文将详细介绍 JDBC 数据库连接池的使用和原理。 1…