10月4日作业

news2024/12/23 10:13:18

server

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //实例化一个服务器
    server = new QTcpServer(this);
    connect(server, &QTcpServer::newConnection, this, &Widget::newConnection_slot);
}

Widget::~Widget()
{
    delete ui;
}
//启动服务器按钮对应的槽函数
void Widget::on_startbtn_clicked()
{
    quint16 port = ui->portEdit->text().toUInt();
    //监听客户端的连接请求
    //函数原型bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
    //参数1:要监听的主机地址,如果是any表示监听任意的主机地址,也可以是特定的主机地址
    //参数2:该服务器的端口号,如果是0,表示由服务器自动指定,一般由程序员指定
    //返回值:成功进入监听,返回true,其他情况,返回false
    if(!server->listen(QHostAddress::Any, port)){
        QMessageBox::information(this, "失败", "监听失败");
        return;
    }else{
        QMessageBox::information(this, "成功", "服务器监听成功");
    }

    //此时,服务器已经成功进入监听状态,如果有客户端向服务器发来连接请求
    //那么该服务器,就会自动发射一个newconnection的信号,我们可以将该信号连接到对应的槽函数中执行相关函数
    //由于只要连接一次,所以可以将该连接放在构造函数中完成
}
//自定义处理newConnection的槽函数的实现
void Widget::newConnection_slot()
{
    qDebug()<<"您有";
    QTcpSocket *s = server->nextPendingConnection();
    //将套接字放入客户端容器中
    clientList.push_back(s);
    //至此,多个客户端已经跟服务器建立连接,并放入容器中了
    //此时,如果有客户端向服务器发来数据,那么对应的客户端套接字就会自动发射一个readyread信号
    //我们可以将该信号连接到自定义的槽函数中,处理相关逻辑
    connect(s, &QTcpSocket::readyRead, this, &Widget::readyRead_solt);
}
//处理readyRead信号的槽函数的声明
void Widget::readyRead_solt()
{
    qDebug()<<"有新的客户端";
    //遍历客户端链表,将无效的客户端移除
    for(int i=0; i<clientList.size(); i++){
        //判断当前套接字是否有效连接
        if(clientList[i]->state() == 0){    //如果是0,表示该套接字是无效连接
            //将该套接字移出链表
            clientList.removeAt(i);
        }
    }

    for(int i=0; i<clientList.size(); i++){
        //求当前客户端套接字中待读字节的字节数
        //返回值:待读数据的字节数,如果等于0,表示无数据待读
        if(clientList[i]->bytesAvailable()){
            //将数据读出来
            QByteArray msg = clientList[i]->readAll();

            //将数据展示到ui界面
            ui->msgWidget->addItem( QString::fromLocal8Bit(msg));

            //将接收到的数据,转发给所有客户端
            for (int j=0; j<clientList.size(); j++) {
                clientList[i]->write(msg);
            }
        }
    }
}

client

#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_startButton_clicked()
{
    //获取用户输入的ip、username和port
    username = ui->usernameEdit->text();
    QString ip = ui->addressEdit->text();
    quint16 port = ui->portEdit->text().toUInt();
    //连接服务器
    socket->connectToHost(ip, port);
}
//处理connected信号的槽函数
void Widget::connected_slot()
{
    QMessageBox::information(this, "连接", "已成功进入聊天室");
    //向服务器发送一条数据:***,进入聊天室
    QString msg = username + "进入聊天室";
    socket->write(msg.toLocal8Bit());
}

void Widget::readyread_slot()
{
    //读取套接字中的信息
    QByteArray msg = socket->readAll();
    //将数据展示到recvList
    ui->recvList->addItem(QString::fromLocal8Bit(msg));
}

void Widget::disconnected_slot()
{
    QMessageBox::information(this, "退出", "退出成功");
}

void Widget::on_sendbtn_clicked()
{
    //获取ui界面输入的内容
    QString msg = username + ":" + ui->sendmsgEdit->toPlainText();

    //发送
    socket->write(msg.toLocal8Bit());

    //清空输入框
    ui->sendmsgEdit->setText("");
}

void Widget::on_stopButton_clicked()
{
    QString msg = username + "离开聊天室";
    socket->write(msg.toLocal8Bit());
    socket->disconnectFromHost();


}

运行截图

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

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

相关文章

CANoe.Diva生成测试用例

Diva目录 一、CANoe.Diva打开CDD文件二、导入CDD文件三、ECU Information四、时间参数设置五、选择是否测试功能寻址六、勾选需要测试服务项七、生成测试用例 一、CANoe.Diva打开CDD文件 CANoe.Diva可以通过导入cdd或odx文件&#xff0c;自动生成全面的测试用例。再在CANoe中导…

Android学习之路(20) 进程间通信

IPC IPC为 (Inter-Process Communication) 缩写&#xff0c;称为进程间通信或跨进程通信&#xff0c;指两个进程间进行数据交换的过程。安卓中主要采用 Binder 进行进程间通信&#xff0c;当然也支持其他 IPC 方式&#xff0c;如&#xff1a;管道&#xff0c;Socket&#xff0…

9.3 链表从指定节点插入新节点

一、从指定节点后方插入 插入逻辑如图&#xff1a; 插入前&#xff1a;A指向B&#xff0c;B指向C 插入后&#xff1a;B为插入点&#xff0c;当要插入D时就要让B指向D&#xff0c;D再指向C&#xff08;插入前B的指向&#xff09; #include <stdio.h>struct Test {int d…

C/C++字符函数和字符串函数详解————内存函数详解与模拟

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 1.前言 2 .memcpy函数 3.memmove函…

mysql双主+双从集群连接模式

架构图&#xff1a; 详细内容参考&#xff1a; 结果展示&#xff1a; 178.119.30.14(主) 178.119.30.15(主) 178.119.30.16(从) 178.119.30.17(从)

【软件设计师-中级——刷题记录6(纯干货)】

目录 管道——过滤器软件体系结构风格优点&#xff1a;计算机英语重点词汇&#xff1a;单元测试主要检查模块的以下5个特征&#xff1a;数据库之并发控制中的事务&#xff1a;并发产生的问题解决方案:封锁协议原型化开发方法&#xff1a; 每日一言&#xff1a;持续更新中... 个…

N. Number Reduction

Problem - 1765N - Codeforces 发现如果是无前导0最小数那么在保证删除k个数时第1位是最小的&#xff0c;第二位一定是相对最小的&#xff0c;且答案第一位和第二位在原位置的间隔是小于等于还可以删除的位数的。 因此&#xff0c;对于原数字长度位n&#xff0c;要删除k&#…

Spring:通过@Lazy解决构造方法形式的循环依赖问题

一、定义2个循环依赖的类 package cn.edu.tju.domain2;import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component;Component public class A {private final B b;public B getB() {return b;}Lazypublic A(B b){this.b b;//Sy…

python获取时间戳

使用 datetime 库获取时间。 获取当前时间&#xff1a; import datetime print(datetime.datetime.now()) . 后面的是微秒&#xff0c;也是一个时间单位&#xff0c;1秒1000000微秒。 转为时间戳&#xff1a; import datetimedate datetime.datetime.now() timestamp date…

计算机系统中丢失MSVCR100.dll的解决方法,三个方法快速搞定

msvcr100.dll 是一个非常重要的系统文件&#xff0c;它属于 Microsoft Visual C Redistributable 的一个组件。这个文件包含了用于 C 编程的一些运行时库&#xff0c;对于许多软件和游戏的运行至关重要。如果您的电脑提示找不到 msvcr100.dll 文件&#xff0c;您可能会遇到一些…

STM32驱动步进电机

前言 &#xff08;1&#xff09;本章介绍用stm32驱动42步进电机&#xff0c;将介绍需要准备的硬件器材、所需芯片资源以及怎么编程及源代码等等。 &#xff08;2&#xff09;实验效果&#xff1a;按下按键&#xff0c;步进电机顺时针或逆时针旋转90度。 &#xff08;3&#xff…

浏览器从输入URL到展示的流程

文章目录 1. URL输入2. DNS解析3. 建立TCP连接4. 发送http或者https请求5. 服务器端响应请求6. 浏览器解析渲染页面7. 断开TCP连接 1. URL输入 输入URL后&#xff0c;浏览器会对URL进行以下的判断 是否合法如果合法&#xff0c;则判断URL是否完整&#xff0c;如果不完整&…

【C 语言进阶(12)】动态内存管理笔试题

文章目录 题目 1题目 2题目 3题目 4 题目 1 运行 Test 函数后的结果是什么&#xff1f; void GetMemory(char* p) {p (char*)malloc(100); }void Test(void) {char* str NULL;GetMemory(str);strcpy(str, "hello world");printf(str); }代码结果 程序崩溃。 代…

openGauss学习笔记-89 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用查询原生编译

文章目录 openGauss学习笔记-89 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用查询原生编译89.1 查询编译&#xff1a;PREPARE语句89.2 运行命令89.3 轻量执行支持的查询89.4 轻量执行不支持的查询89.5 JIT存储过程89.6 MOT JIT诊断89.6.1 mot_jit_detai…

MATLAB 函数签名器

文章目录 MATLAB 函数签名器注释规范模板参数类型 kind数据格式 type选项的支持 使用可执行程序封装为m函数程序输出 编译待办事项推荐阅读附录 MATLAB 函数签名器 MATLAB 函数签名器 (FUNCSIGN) &#xff0c;在规范注释格式的基础上为函数文件或类文件自动生成函数签名&#…

c++ 基础知识(一)

文章目录 1. C关键字 2. 命名空间 3. C输入&输出 4. 缺省参数 文章内容 1. C关键字(C98) C总计63个关键字&#xff0c;C语言32个关键字 ps&#xff1a;下面我们只是看一下C有多少关键字&#xff0c;不对关键字进行具体的讲解。后面我学了以后再细讲。 2. 命名空间 …

简单查找重复文本文件

声明这是最初 我的提问给个文本分类清单input查找文件夹下 .py .txt .excel .word 一模一样的文本不是找文件名 找相同格式下的文件文本是否一样 文件单独复制到文件夹下两个文件全部复制到文件夹下 print 打印相同文本文件的名字 比如查找到了3.py与4.5.是.py文件中的文本文件…

Java基础API---euqals 小知识

导入&#xff1a; 大家有没有遇到自定义的类&#xff0c;无法用equals方法比较成员属性呀&#xff1f;那是因为需要重写equals方法 重写原理这里偷个懒&#xff0c;idea中 altinsert 快捷键&#xff0c;快速实现重写equals噢&#xff01; Student类&#xff1a; package ob…

【C++】基础入门

万字复习C基础入门语法&#xff0c;适合学过C的朋友用来复习查阅&#xff0c;可能不太适合0基础的朋友。 一.c初识 (1) 第一个c程序 最简单的格式&#xff1a; // 导入头文件 #include<iostream> // 简化对命名空间std下函数和对象的使用 using namespace std; // …

阿里云服务器免费申请入口_注册阿里云免费领4台服务器

注册阿里云账号&#xff0c;免费领云服务器&#xff0c;最高领取4台云服务器&#xff0c;每月750小时&#xff0c;3个月免费试用时长&#xff0c;可快速搭建网站/小程序&#xff0c;部署开发环境&#xff0c;开发多种企业应用。阿里云百科分享阿里云服务器免费领取入口、免费云…