复习 --- QT服务器客户端

服务器:

头文件:

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QTcpServer>
#include<QTcpSocket>
#include<QMessageBox>
#include<QDebug>
#include<QList>
#include<QListWidget>
#include<QLabel>
#include<QLineEdit>
#include<QPushButton>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;

    //客户端指针
    QTcpSocket *client;
    //存储用户名
    QString uname;

    //聊天框
    QListWidget *text;
    //消息发送框
    QLineEdit *msg;
    //发送按钮
    QPushButton *send;
    //用户名、
    QLabel *userLab;
    //IP
    QLabel *ipLab;
    //PORT
    QLabel *portLab;
    //用户输入框
    QLineEdit *unameEdit;
    //IP输入框
    QLineEdit *ipEdit;
    //端口输入框
    QLineEdit *portEdit;
    //连接服务器按钮
    QPushButton *bconnect;
    //断开服务器按钮
    QPushButton *bdisconnect;

public slots:
    //连接按钮槽函数
    void connectBtn_clicked();
    //声明自定义处理connected信号的槽函数
    void connected_slot();
    //声明自定义处理readyRead信号的槽函数
    void readyRead_slot();
    //声明自定义处理disconnected信号的槽函数
    void disconnected_slot();
    //发送按钮槽函数
    void  sendBtn_clicked();
    //断开连接槽函数
    void disconnectBtn_clicked();
};
#endif // WIDGET_H

widget.cpp文件

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setFixedSize(720,680);

    //聊天框
    text = new QListWidget(this);
    text->setFixedSize(720,400);
    //消息发送框
    msg = new QLineEdit(this);
    msg->resize(500,50);
    msg->move(10,420);
    //发送按钮
    send = new QPushButton(this);
    send->setText("发送");
    send->resize(150,50);
    send->move(520,420);
    //用户名
    userLab = new QLabel(this);
    userLab->setText("用户名:");
    userLab->setAlignment(Qt::AlignCenter);
    userLab->resize(100,30);
    userLab->move(30,500);
    //IP
    ipLab = new QLabel(this);
    ipLab->setText("IP:");
    ipLab->setAlignment(Qt::AlignCenter);
    ipLab->resize(100,30);
    ipLab->move(30,550);
    //PORT
    portLab = new QLabel(this);
    portLab->setText("Port:");
    portLab->setAlignment(Qt::AlignCenter);
    portLab->resize(100,30);
    portLab->move(30,600);
    //用户输入框
    unameEdit = new QLineEdit(this);
    unameEdit->resize(300,30);
    unameEdit->move(140,500);
    //IP输入框
    ipEdit = new QLineEdit(this);
    ipEdit->resize(300,30);
    ipEdit->move(140,550);
    //端口输入框
    portEdit = new QLineEdit(this);
    portEdit->resize(300,30);
    portEdit->move(140,600);
    //连接服务器按钮
    bconnect = new QPushButton(this);
    bconnect->resize(120,50);
    bconnect->setText("连接");
    bconnect->move(520,500);
    //断开服务器按钮
    bdisconnect = new QPushButton(this);
    bdisconnect->resize(120,50);
    bdisconnect->setText("断开连接");
    bdisconnect->move(520,580);

    client = new QTcpSocket(this);
    //连接按钮信号
    connect(bconnect,&QPushButton::clicked,this,&Widget::connectBtn_clicked);
    //连接上后客户端自动发送一个connected信号,只需要连接一次
    connect(client,&QTcpSocket::connected,this,&Widget::connected_slot);
    //如果服务器有数据发送给该客户端,那么该套接字就会自动发射一个readyRead信号
    connect(client, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
    //发送按钮
    connect(send,&QPushButton::clicked,this,&Widget::sendBtn_clicked);
    //当成功与服务器断开连接后,该客户端就会自动发射一个disconnected的信号
    connect(client, &QTcpSocket::disconnected, this, &Widget::disconnected_slot);
}

Widget::~Widget()
{
    delete ui;

}

//连接按钮槽函数
void Widget::connectBtn_clicked()
{
    //获取ip和端口
    QString ip = ipEdit->text();
    quint16 port = portEdit->text().toUInt();

    //连接主机
    client->connectToHost(ip,port);
}
//声明自定义处理connected信号的槽函数
void Widget::connected_slot()
{
    QMessageBox::information(this,"","连接服务器成功");

    uname = unameEdit->text();
    QString msgs = uname+":进入聊天室";

    client->write(msgs.toLocal8Bit());

    msg->setEnabled(true);
    send->setEnabled(true);
    bdisconnect->setEnabled(true);
    unameEdit->setEnabled(false);
    ipEdit->setEnabled(false);
    portEdit->setEnabled(false);
    bconnect->setEnabled(false);

}
//声明自定义处理readyRead信号的槽函数
void Widget::readyRead_slot()
{
    //接收到服务器消息后
    QByteArray msgbox = client->readAll();
    //显示
    text->addItem(QString::fromLocal8Bit(msgbox));
}
//声明自定义处理disconnected信号的槽函数
void Widget::disconnected_slot()
{
    QString msgbox = uname+":离开聊天室";
    client->write(msgbox.toLocal8Bit());
    //断开后客户端会发送一个disconnected信号
    client->disconnectFromHost();
}
//发送按钮槽函数
void Widget::sendBtn_clicked()
{
    QString msgbox = msg->text();
    msgbox = uname+":"+msgbox;
    //发送
    client->write(msgbox.toLocal8Bit());
    msg->clear();

}
//断开连接槽函数
void Widget::disconnectBtn_clicked()
{
    QMessageBox::information(this,"","成功断开");
    msg->setEnabled(false);
    send->setEnabled(false);
    bdisconnect->setEnabled(false);
    unameEdit->setEnabled(true);
    ipEdit->setEnabled(true);
    portEdit->setEnabled(true);
    bconnect->setEnabled(true);
}

客户端

头文件

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QTcpServer>
#include<QTcpSocket>
#include<QMessageBox>
#include<QDebug>
#include<QList>
#include<QListWidget>
#include<QLabel>
#include<QLineEdit>
#include<QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
    //定义服务器指针
    QTcpServer *server;
    //定义客户端容器
    QList<QTcpSocket*> socketList;

    //对话框
    QListWidget *text;
    //端口号
    QLabel * l_port;
    //端口输入框
    QLineEdit *edit_port;
    //启动按钮
    QPushButton *bstart;

private slots:
    //按键槽函数
    void start_clicked();
    //连接槽函数
    void newConnection_slot();
    //readyRead信号处理槽函数
    void readyRead_slot();

};
#endif // WIDGET_H

widget.cpp

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->setFixedSize(680,500);

    //对话框
    text = new QListWidget(this);
    text->setFixedSize(680,350);
    //端口号
    l_port = new QLabel(this);
    l_port->setText("端口号:");
    l_port->resize(50,30);
    l_port->move(50,400);

    //端口输入框
    edit_port = new QLineEdit(this);
    edit_port->resize(380,30);
    edit_port->move(120,400);
    //启动按钮
    bstart = new QPushButton(this);
    bstart->setText("启动服务器");
    bstart->resize(100,30);
    bstart->move(520,400);

    server = new QTcpServer(this);

    connect(bstart,&QPushButton::clicked,this,&Widget::start_clicked);
}

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

void Widget::start_clicked()
{
    qDebug()<<"ok";  //测试
    //判断输入框中是否有内容
    if(edit_port->text() == NULL)
    {
        QMessageBox::information(this,"错误","端口号为空!");
    }
    else
    {
        //获取输入框中的内容
        quint16 port = edit_port->text().toUInt();
        qDebug()<<port;
        QString ip = "192.168.1.2";
        QHostAddress address(ip);

        //将服务器设置成监听状态,监听客户段发来的连接请求
        if(server->listen(QHostAddress::Any,port))
        {
            QMessageBox::information(this,"","服务器启动成功");
        }
        else
        {
            QMessageBox::information(this,"","服务器启动失败");
        }

        //此时服务器已经进入监听状态,客户段发来连接请求,服务器就会自动发射一个newConnext信号
        connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);
    }
}

void Widget::newConnection_slot()
{
    qDebug()<<"有客户连接";
    //获取最新连接的客户段套接字
    QTcpSocket *client = server->nextPendingConnection();
    //将套接字放入客户端容器
    socketList.push_back(client);

    //监听套接字,有数据则客户端会发送一个readyRead信号
    connect(client,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
}

void Widget::readyRead_slot()
{
    //移除无效客户端
    for (int i = 0;i<socketList.count();i++)
    {
        //套接字状态为0表示无效客户端
        if(socketList.at(i)->state() == 0)
        {
            socketList.removeAt(i);
        }
    }
    //遍历套接字有消息发送给其他客户端
    for (int i = 0;i<socketList.count();i++)
    {
        //获取套接字是否有有效数据
        if(socketList.at(i)->bytesAvailable() != 0)
        {
            //获取套接字内信息
            QByteArray msg = socketList.at(i)->readAll();
            text->addItem(QString::fromLocal8Bit(msg));
            for (int j = 0;j<socketList.count();j++)
            {
                socketList.at(j)->write(msg);

            }
        }
    }
}
相关推荐
春蕾夏荷_7282977252 小时前
qt ElaWidgetTools第一个实例
开发语言·qt
IDIOT___IDIOT9 小时前
Linux mount 命令
linux·运维·服务器
韭菜钟9 小时前
在Qt中用cmake实现类似pri文件的功能
开发语言·qt·系统架构
暗流者9 小时前
AAA 服务器与 RADIUS 协议笔记
运维·服务器·笔记
青草地溪水旁12 小时前
服务发现实例和服务实例是不同的
服务器·服务发现·服务实例
于冬恋13 小时前
RabbitMQ高级
服务器·网络·rabbitmq
韭菜钟14 小时前
Qt从qmake迁移到cmake的记录
开发语言·qt
算力魔方AIPC14 小时前
如何用算力魔方4060安装PaddleOCR MCP 服务器
运维·服务器
tan77º14 小时前
【Linux网络编程】分布式Json-RPC框架 - 项目设计
linux·服务器·网络·分布式·网络协议·rpc·json
Ray Song15 小时前
【Linux】 wget、curl 用法区别
linux·运维·服务器·curl·wget