复习 --- 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);

            }
        }
    }
}
相关推荐
十五年专注C++开发6 小时前
Qt .pro配置gcc相关命令(三):-W1、-L、-rpath和-rpath-link
linux·运维·c++·qt·cmake·跨平台编译
摸鱼仙人~7 小时前
如何设计一个既提供绘图Tools又提供example_data的MCP服务器:
android·服务器·javascript
Cai junhao7 小时前
【Qt】Qt控件
开发语言·c++·笔记·qt
uyeonashi7 小时前
【QT系统相关】QT网络
开发语言·网络·c++·qt
Simple_core8 小时前
Qt3d中的材质--PBR材质
qt·3d·材质
沧浪之水120101378 小时前
linux常用命令
linux·运维·服务器
我真不会起名字啊10 小时前
Qt如何生成和使用DLL动态链接库
开发语言·qt
小胖同学~10 小时前
SQL 增删改查 —— 笔记篇
服务器·数据库
亮亮亮亮!10 小时前
Linux之Python定制篇——新版Ubuntu24.04安装
linux·运维·服务器
巨龙之路11 小时前
如何在Windows上使用qemu安装ubuntu24.04服务器?
运维·服务器·windows