10.10 QT服务器与客户端

客户端

H文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>  //客户端类
#include <QMessageBox>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_2_clicked();
    void connected_slot();         //定义处理connected信号的槽函数
    void readyRead_slot();          //定义处理readyRead信号的槽函数
    void on_pushButton_clicked();

    void on_pushButton_3_clicked();
    void disconnected_slot();

private:
    Ui::Widget *ui;
    QTcpSocket *client;     //客户端指针
    QString usernName;      //储存用户名

};
#endif // WIDGET_H

源文件

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

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //实例化一个客户端对象
    client = new QTcpSocket(this);
    //将客户端套接字的connectet的信号连接到自己的槽函数中
    connect(client,&QTcpSocket::connected,this,&Widget::connected_slot);
    //当服务器向客户端发来消息后,那么客户端套接字自动发射一个readRead信号
    //我们可以将信号连接到自定义的槽函数中处理相关逻辑
    connect(client,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);

    //将disconnected信号连接到槽函数中
    connect(client,&QTcpSocket::disconnected,this,&Widget::disconnected_slot);

}

Widget::~Widget()
{
    delete ui;
}

//连接服务器按钮对应的槽函数
void Widget::on_pushButton_2_clicked()
{
    //先获取ui界面上的数据
    usernName = ui->ten_name->text();
    QString ip =ui->ten_ip->text();
    quint16 port = ui->ten_port->text().toUInt();


    client->connectToHost(ip,port);
    //至此,表示已经向服务器发生连接请求了,如果成功连接服务器
    //那么该套接字就会自动发生一个connected的信号

}
//自定义处理connected信号的槽函数
void Widget::connected_slot()
{
    QMessageBox::information(this,"提示","连接服务器成功");

    QString msg=usernName + "进入聊天室";
   //将消息发送给服务器
    client->write(msg.toLocal8Bit());
}
//之定义出来readyRead新号的曹函数的实现
void Widget::readyRead_slot()
{
    //读取套接字中的数据库
    QByteArray msg=client->readAll();
    //将消息展示到ui界面上
    ui->listWidget->addItem(QString::fromLocal8Bit(msg));
}

//发消息对应的槽函数
void Widget::on_pushButton_clicked()
{
    //获取UI界面上的消息编辑器上的文本内容
    QString msg=usernName + ":"+ui->lineEdit->text();
    //将消息发送给服务器
    client->write(msg.toLocal8Bit());
    //清空编辑器的文本内容
    ui->lineEdit->clear();

}

//断开服务器按钮对应的槽函数
void Widget::on_pushButton_3_clicked()
{
    //向服务器发生 XXX:离开聊天室
    QString msg=usernName + ":离开聊天室";
    //将消息发给服务器
    client->write(msg.toLocal8Bit());

    //将套接字与服务器断开
    client->disconnectFromHost();
    //当客户端成功与服务器断开连接后,该客户端自动发一个disconneted的信号
    //
}

void Widget::disconnected_slot()
{
    QMessageBox::information(this,"提示","断开连接");
}

服务器

h文件

#ifndef FWQ_H
#define FWQ_H

#include <QWidget>
#include <QTcpServer>
#include <QList>
#include <QTcpSocket>
#include <QMessageBox>
#include <QDebug>



QT_BEGIN_NAMESPACE
namespace Ui { class fwq; }
QT_END_NAMESPACE

class fwq : public QWidget
{
    Q_OBJECT

public:
    fwq(QWidget *parent = nullptr);
    ~fwq();

private slots:
    void on_pushButton_clicked();
    void newconnetion_slots();
    void readyRead_slot();
private:
    Ui::fwq *ui;
    //定义服务器指针
    QTcpServer *server;
    //定义客户端
    QList<QTcpSocket *>clientlist;
};
#endif // FWQ_H

源文件

#include "fwq.h"
#include "ui_fwq.h"

fwq::fwq(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::fwq)
{
    ui->setupUi(this);
    // 实例化服务器对象
    server=new QTcpServer(this);
    //将服务器的newconnetion信号连接到定义的槽函数中执行相关逻辑
    connect(server,&QTcpServer::newConnection,this,&fwq::newconnetion_slots);
}

fwq::~fwq()
{
    delete ui;
}


void fwq::on_pushButton_clicked()
{
    if(ui->pushButton->text()=="启动服务器")
    {
        //启动服务器
        //获取UI界面上的端口号
        quint16 port =ui->ten1->text().toUInt();
        //启动监听
        //函数原型:bool listen(const QHostAddress &address=QHosAddress::Any,quint10 port =0)
        //参数1:要监听的IP地址,HEostAddress::Any表示监听任意一台主机
        //参数2:服务器端口号,如果天0表示让系统自动分配端口号
        //返回值:成功返回监听返回值真(成功启动服务器) 否则返回假
        if(!server->listen(QHostAddress::Any,port))
        {
            QMessageBox::information(this,"提示","服务器启动失败");
            return ;
        }else
        {
            QMessageBox::information(this,"提示","服务器启动成功");
        }
        //程序执行到此,表示服务器启动成功了,此时如果有客户端向服务器发生连接请求,该服务器会自动发射一个newconnection信号
        //我们就可以将该信号连接到之定义的曹函数中执行逻辑,由于连接只需要一次,我们可以写在构造函数中

        //跟新按钮文件
        ui->pushButton->setText("关闭服务器");
    }else
    {
        //关闭服务器逻辑
            server->close();
        //跟新按钮文本内容
        ui->pushButton->setText("启动服务器");
    }
}
//处理newconnetion信号对应的槽函数定义
void fwq::newconnetion_slots()
{
  //  QMessageBox::information(this,"提示","有新客户发来连接请求");
    qDebug()<<"有新客户端发来连接请求";
    //获取最新客户端的套接字

    QTcpSocket *s = server->nextPendingConnection();
    //该套接字放入到客户端链表中
    clientlist.push_back(s);
    //程序执行至此,一个服务器和多个客户端就已经建立了连接
    //当某个客户端向服务器发送消息后,该套接字就会自动发生一个readyRead信号
    //我们就可以将该信号连接到自定义的曹函数中执行先关逻辑

    connect(s, &QTcpSocket::readyRead,this,&fwq::readyRead_slot);


}

void fwq::readyRead_slot()
{
   //循环遍历所有客户端,查看哪一个客户端中有消息待续
  for(auto val:clientlist)
    {


       if(val->bytesAvailable())
       {
            //表示当前套接字发消息了,将当前套接字读取出来

          QByteArray msg= val->readAll();
          //将该消息展示到UI界面上
         ui->listWidget->addItem(QString::fromLocal8Bit(msg));
                  for(auto key:clientlist)
           {
                key->write(msg);
            }
        }
   }
}
相关推荐
Minyy1114 分钟前
小程序项目实践(一)--项目的初始化以及前期的准备工作
开发语言·前端·git·小程序·gitee·uni-app
今晚吃什么呢?14 分钟前
module
开发语言·javascript·ecmascript
碳苯21 分钟前
【rCore OS 开源操作系统】Rust 异常处理
开发语言·人工智能·后端·rust·操作系统·os
Lightning-py30 分钟前
Linux-控制脚本
linux·运维·服务器
尘浮生38 分钟前
Java项目实战II基于Java+Spring Boot+MySQL的桂林旅游景点导游平台(源码+数据库+文档)
java·开发语言·数据库·spring boot·mysql·maven·intellij-idea
这孩子叫逆1 小时前
axios 使用
开发语言·javascript·ecmascript
careathers1 小时前
【Python】物流行业数据分析与可视化案例
开发语言·python·数据分析
多多*1 小时前
OJ在线评测系统 微服务高级 网关跨域权限校验 集中解决跨域问题 拓展 JWT校验和实现接口限流降级
java·开发语言·微服务·云原生·架构·maven
另类程序员1321 小时前
安装jdk安装开发环境与maven
java·开发语言
姆路1 小时前
Qt文件对话框、颜色对话框、字体对话框、输入对话框
c++·qt