国庆 day 5

QT实现TCP服务器客户端搭建的代码,现象

服务器

cs 复制代码
#include "widget.h"
#include "ui_widget.h"
 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    server = new QTcpServer(this);
    connect (server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::on_startBtn_clicked()
{
    quint16 port = ui->portEdit->text().toUInt();
    if(!server->listen(QHostAddress::Any, port))
        {
            QMessageBox::information(this, "失败", "监听失败");
            return ;
        }else
        {
            QMessageBox::information(this, "成功", "服务器启动成功");
        }
}
 
void Widget::newConnection_slot()
{
    qDebug()<<"您有新的客户端发来连接请求";
    QTcpSocket *s = server->nextPendingConnection();
    clientList.push_back(s);
    connect(s, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
}
 
void Widget::readyRead_slot()
{
    qDebug()<<"有新的客户端消息发来了";
 
    //遍历客户端链表,将无效的客户端移除
    for(int i=0; i<clientList.size(); i++)
    {
        //判断当前套接字是否是有效连接
        //函数原型: SocketState state() const;
        //参数:无
        //返回值:套接字的状态,如果是0,表示该套接字为无效连接
        if(clientList[i]->state() ==0)
        {
            //将该套接字移除客户端容器
            clientList.removeAt(i);
        }
    }
    //遍历客户端链表,判断是哪个客户端发来的数据
    for(int i=0; i<clientList.size(); i++)
    {
        //函数原型:qint64 bytesAvailable() const override;
        //功能:求当前客户端套接字中待读数据的字节数
        //参数:无
        //返回值:待读数据的字节数,如果是0,表示无数据待读
        if(clientList[i]->bytesAvailable() != 0)
        {
            //将该套接字中的数据读取出来
            QByteArray msg = clientList[i]->readAll();
 
            //将数据展示到ui界面
            ui->msgWidget->addItem( QString::fromLocal8Bit(msg) );
 
            //将接受到的数据,转发给所有客户端
            for(int j=0; j<clientList.size(); j++)
            {
                clientList[j]->write(msg);
            }
        }
    }
}

客户端

cs 复制代码
#include "widget.h"
#include "ui_widget.h"
 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    socket = new QTcpSocket(this);
    //此时,已经向服务器发送连接请求了,如果成功连接服务器,那么该客户端就会自动发射一个connected的信号
    //我们可以将该信号连接到自定义的槽函数中处理逻辑
    //由于只需要连接一次,所以将连接写在构造函数中
    connect(socket, &QTcpSocket::connected, this, &Widget::connected_slot);
 
    //如果服务器向客户端发来消息,那么该客户端就会自动发射一个readyRead信号
    //我们可以将该进行连接到自定义的槽函数中处理相关逻辑
    connect(socket, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
 
    //当成功与服务器断开连接后,该客户端会自动发射一个disconnected的信号
    //我们可以将该信号连接到自定义的槽函数中处理相关逻辑
    //由于该连接只需连接一次即可,所以放在构造函数中进行
    connect(socket, &QTcpSocket::disconnected, this, &Widget::disconnected_slot);
}
Widget::~Widget()
{
    delete ui;
}
 
//连接服务器按钮对应的槽函数
void Widget::on_connectBtn_clicked()
{
    //获取ui界面上的相关信息
    userName = ui->userNameEdit->text();         //获取用户名
    QString ip = ui->ipEdit->text();            //主机地址
    quint16 port = ui->portEdit->text().toUInt();        //端口号
 
    //函数原型:virtual void connectToHost(const QHostAddress &address, quint16 port);
    //功能:将客户端连接到给定的服务器
    //参数1:服务器的主机地址
    //参数2:端口号
    //返回值:无
    socket->connectToHost(ip, port);
 
    //此时,已经向服务器发送连接请求了,如果成功连接服务器,那么该客户端就会自动发射一个connected的信号
    //我们可以将该信号连接到自定义的槽函数中处理逻辑
    //由于只需要连接一次,所以将连接写在构造函数中
 
}
 
//处理connected信号的槽函数的定义
void Widget::connected_slot()
{
    QMessageBox::information(this, "成功", "您已经成功进入聊天室");
    //向服务器发送一条数据:***:进入聊天室
    QString msg = userName +": 进入聊天室";
 
    socket->write(msg.toLocal8Bit());          //将数据写给服务器
}
 
//处理readyRead信号的槽函数的定义
void Widget::readyRead_slot()
{
    //读取套接字中的信息
    QByteArray msg = socket->readAll();
 
    //将数据展示到ui界面
    ui->msgWidget->addItem(QString::fromLocal8Bit(msg));
}
 
//发送按钮对应的槽函数
void Widget::on_sendBtn_clicked()
{
    //获取ui界面输入的内容
    QString msg =userName+ ": " + ui->msgEdit->text();
 
    //发送给服务器
    socket->write(msg.toLocal8Bit());
 
    //清空编辑框内容
    ui->msgEdit->clear();
}
 
//断开服务器按钮对应的槽函数
void Widget::on_disconnectBtn_clicked()
{
    QString msg = userName +": 离开聊天室";
    socket->write(msg.toLocal8Bit());
 
    //断开连接
    //函数原型: virtual void disconnectFromHost();
    socket->disconnectFromHost();
 
    //当成功与服务器断开连接后,该客户端会自动发射一个disconnected的信号
    //我们可以将该信号连接到自定义的槽函数中处理相关逻辑
    //由于该连接只需连接一次即可,所以放在构造函数中进行
}
 
//disconnected信号对应槽函数的定义
void Widget::disconnected_slot()
{
    QMessageBox::information(this, "提示", "退出成功");
}
相关推荐
csdn_zhangchunfeng1 小时前
Qt之slots和Q_SLOTS的区别
开发语言·qt
Larry_Yanan5 小时前
Qt网络开发之基于 QWebEngine 实现简易内嵌浏览器
linux·开发语言·网络·c++·笔记·qt·学习
一然明月8 小时前
Qt QML 锚定(Anchors)全解析
java·数据库·qt
一只爱学习的小鱼儿8 小时前
使用QT编写粒子显示热力图效果
开发语言·qt
大树学长8 小时前
【QT开发】Redis通信相关(一)
redis·qt
笨笨马甲8 小时前
Qt 人脸识别
开发语言·qt
山上三树9 小时前
Qt QObject介绍
开发语言·qt
山上三树9 小时前
QObject、QWidget、Widget三者的关系
qt
坚定学代码9 小时前
qt c++ 局域网聊天小工具
c++·qt·个人开发
笨笨马甲10 小时前
Qt network开发
开发语言·qt