qt服务器 网络聊天室

widget.cpp

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()
{
    //获取ui界面上的端口号
    quint16 port = ui->portEdit->text().toUInt();

    //将服务器设置为监听状态
    //bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
    //功能:监听客户端发来的连接请求
    //参数1:要坚听的主机地址,any表示监听任意主机地址,也可以给定特定主机地址
    //参数2:提供的端口号,如果时0,表示让系统自动分配端口号
    //返回值:bool,成功监听返回true,失败返回false
    if (server->listen(QHostAddress::Any, port))
    {
        QMessageBox::information(this, "", "服务器启动成功");
    }
    else
    {
        QMessageBox::information(this, "", "服务器启动失败");
    }

    //此时服务器已经进入监听状态,如果有客户端发来连接请求,那么该服务器就会自动发射一个newConnection信号
    //可以将该信号连接到自定义的槽函数中处理心连接的套接字
    connect(server, &QTcpServer::newConnection, this, &Widget::newConnection_slot);

}

//处理newConnection信号的槽函数的实现
void Widget::newConnection_slot()
{
    qDebug() << "有新客户端发来连接";

    //获取最新连接的客户端套接字
    //函数原型:virtual QTcpSocket *nextPendingConnection();
    //功能:获取最新连接客户端的套接字
    //参数:无
    //返回值:套接字指针
    QTcpSocket *s = server->nextPendingConnection();

    //将该套接字放入到客户端容器中
    socketList.push_back(s);

    //此时客户端与服务器已经建立起了连接
    //如果有客户端向服务器发来数据,那么该客户端会自动发射一个readyRead信号
    //可以在该信号对应的槽函数中,获取客户端中的数据
    connect(s, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
}

//关于readyRead信号对应槽函数的实现
void Widget::readyRead_slot()
{
    //移除无效客户端
    for (int i = 0; i < socketList.count(); i++)
    {
        //        socketList.at(i)->state();  //任意一个客户端的状态
        //函数原型:SocketState state() const;
        //功能:返回套接字状态
        //参数:无
        //返回值:套接字状态,是个枚举值,如果是0,表示无效连接
        if (socketList.at(i)->state() == 0)
        {
            //移除该客户端
            socketList.removeAt(i);     //将下标为i的套接字从链表中移除
        }
    }

    //遍历客户端套接字去寻找哪个客户端有数据待读
    for (int i = 0; socketList.count(); i++)
    {
        //判断当前套接字是否有数据待读
        //函数原型:qint64 bytesAvailable() const override;
        //功能:求出当前套接字待读数据的个数
        //参数:无
        //返回值:待读数据的个数
        if (socketList.at(i)->bytesAvailable() != 0)
        {
            //说明当前套接字中有数据
            //读取当前套接字中的数据
            //函数原型:QByteArray readAll();
            //功能:读取套接字中所有数据
            //参数:无
            //返回值:QByteArray读取下来的数据
            QByteArray msg = socketList.at(i)->readAll();

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

            //将数据发送给所有客户端
            for (int j = 0; j < socketList.count(); j++)
            {
                //将数据写入到所有客户端套接字中
                socketList.at(j)->write(msg);
            }
        }
    }
}
相关推荐
利刃大大14 小时前
【高并发服务器:HTTP应用】十六、HttpContext上下文模块 && HttpServer服务器模块&& 服务器测试
运维·服务器·http·高并发·项目
是专家不是砖家14 小时前
rk3562 udp发送带宽500Mbps出现丢包问题
网络·网络协议·udp·rk3562·udp丢包·t507
wanhengidc14 小时前
云手机通常使用什么架构
服务器·网络·安全·游戏·智能手机·云计算
emiya_saber14 小时前
Linux 文件系统基本管理
linux·运维·服务器
夜月yeyue14 小时前
Linux 内核驱动加载机制
linux·服务器·stm32·嵌入式硬件
好记忆不如烂笔头abc15 小时前
Oracle19c rac两节点实例test,在节点1查看监听状态没有test1,但在节点2可以看到test2
运维·服务器
在路上看风景15 小时前
5.1 路由选择算法
网络
xiaoxiongip66615 小时前
假设两个设备在不同网段,网关怎么设置才能通呢
网络·爬虫·python·https·智能路由器
阿猿收手吧!16 小时前
【环境配置】vscode远程连接云服务器死机问题
运维·服务器
Li zlun16 小时前
TCP/IP协议:互联网的基石与通信灵魂
网络·网络协议·tcp/ip