2022/9/5——qt中实现基于TCP的网络聊天室

本次搭建需要使用关于TCP的库,所以需要在配置文件中加入

QT       += network

一、服务器的搭建

1、ui界面的构建

2022/9/5——qt中实现基于TCP的网络聊天室_第1张图片 

2、widget.h

主要是头文件的包络和函数的声明

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 
#include 
#include 

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_startBtn_clicked();

    void on_newConnection_slot();

    void on_readyRead_slot();

    void send(QString mes);
private:
    Ui::Widget *ui;

    //定义一个服务器指针
    QTcpServer *server;

    //定义一个客户端指针,存放连接的客户端
    QList socketList;
};
#endif // WIDGET_H

3、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);
}

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

//启动按钮对应的槽函数
void Widget::on_startBtn_clicked()
{
    quint16 port = quint16(ui->portEdit->text().toInt());

    //将服务器设置为监听状态
    server->listen(QHostAddress::Any,port);

    //将相应的控件设置为不可用状态
    ui->portEdit->setEnabled(false);
    ui->startBtn->setEnabled(false);

    //当有新的客户端连接到该服务器后,会出现
    connect(server,&QTcpServer::newConnection,this,&Widget::on_newConnection_slot);
}

void Widget::on_newConnection_slot()
{
    QTcpSocket * socket = server->nextPendingConnection();

    //将该套接字放入套接字链表中
    socketList.append(socket);

    //当服务器接收到客户端传过来的消息时,
    connect(socket, &QTcpSocket::readyRead, this, &Widget::on_readyRead_slot);
}

void Widget::on_readyRead_slot()
{
    //判断客户端套接字是否有效,如果无效则移除
    for(int i=0; istate() == false)
        {
            socketList.removeAt(i);
        }
    }

    //遍历客户端的链表,判断是哪一个客户端发送消息
    for(quint16 j=0; jbytesAvailable())
        {
            QString mes = QString::fromLocal8Bit( socketList.at(j)->readAll());
            //将消息展示到list widget上
            ui->listWidget->addItem(mes);
            //同时还要把该消息进行广播
            send(mes);
        }
    }
}

二、客户端的搭建

1、ui界面的构建

2022/9/5——qt中实现基于TCP的网络聊天室_第2张图片

2、widget.h

主要是头文件的包络和函数的声明

#ifndef CHATCLIENT_H
#define CHATCLIENT_H

#include 
#include 
#include 

QT_BEGIN_NAMESPACE
namespace Ui { class chatClient; }
QT_END_NAMESPACE

class chatClient : public QWidget
{
    Q_OBJECT

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

private slots:
    void on_connectBtn_clicked();

    void on_connected_slot();

    void on_disconnected_slot();

    void on_readyRead_slot();
    void on_sendBtn_clicked();

private:
    Ui::chatClient *ui;

    //定义客户端套接字指针
    QTcpSocket *socket;

    //定义用户名;
    QString usename;

    //定义bool类型数据,表示连接状态
    bool isok;
};
#endif // CHATCLIENT_H

3、widget.cpp

主要是对于函数的定义与服务器的实例化,对客户端连接时和断开连接时发出的信号进行处理并实现相应功能

#include "chatclient.h"
#include "ui_chatclient.h"
#include 

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

    socket = new QTcpSocket(this);

    //给连接状态初始值
    isok =false;

    //将connect信号连接到自定义的槽函数
    connect(socket,&QTcpSocket::connected,this,&chatClient::on_connected_slot);

    //将disconnect信号连接到自定义的槽函数
    connect(socket,&QTcpSocket::disconnected,this,&chatClient::on_disconnected_slot);

    //
    connect(socket,&QTcpSocket::readyRead,this,&chatClient::on_readyRead_slot);
}

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


void chatClient::on_connectBtn_clicked()
{
    QString ip = ui->ipEdit->text();
    quint16 port = ui->porEdit->text().toInt();
    //判断连接状态
    if(isok == false)
    {
        //连接服务器
        socket->connectToHost(QHostAddress(ip),port);
        //将按钮文本改为"断开连接"
        ui->connectBtn->setText("断开连接");
        isok = true;
        //将相应的控件设置为不可用状态
        ui->ipEdit->setEnabled(false);
        ui->porEdit->setEnabled(false);
        ui->userEdit->setEnabled(false);
    }else
    {
        usename = ui->userEdit->text();
        QString mes = usename + "离开群聊";

        socket->write(mes.toLocal8Bit());
        //断开服务器
        socket->disconnectFromHost();

        ui->connectBtn->setText("连接服务器");
        isok = false;
        //将相应的控件恢复为可用状态
        ui->ipEdit->setEnabled(true);
        ui->porEdit->setEnabled(true);
        ui->userEdit->setEnabled(true);
    }
}

void chatClient::on_connected_slot()
{
    usename = ui->userEdit->text();
    QString mes = usename + "加入群聊";

    socket->write(mes.toLocal8Bit());
}

void chatClient::on_disconnected_slot()
{

}
//readyRead信号对应的槽函数的定义
void chatClient::on_readyRead_slot()
{
    //获取套接字中的数据
    QString mes = QString::fromLocal8Bit(socket->readAll());

    ui->listWidget->addItem(mes);
}


void chatClient::on_sendBtn_clicked()
{
    usename = ui->userEdit->text();
    QString mes = usename + ":" + ui->mesEdit->text();

    socket->write(mes.toLocal8Bit());

    ui->mesEdit->clear();
}

你可能感兴趣的:(qt学习,服务器,qt)