QT day5

服务器 

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

    //将服务器设置成监听状态
    if(server->listen(QHostAddress::Any, port) == 0)
    {
        QMessageBox::critical(this, "失败", "服务器启动失败");
        return;
    }
    else
    {
        QMessageBox::information(this, "成功", "服务器启动成功");
    }

    //此时表明服务器启动成功,并对客户端连接进行监听,如果有客户端向服务器发来连接请求,则该服务器就会自动发射一个newConnection的信号
    //我们可以将该信号连接到对应的槽函数中处理相关逻辑
    connect(server, &QTcpServer::newConnection, this, &Widget::newConnection_slot);

}

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

    //获取最新连接的客户端套接字
    QTcpSocket *s = server->nextPendingConnection();

    //将获取的套接字存放到客户端容器中
    clientlist.push_back(s);

    //此时客户端就和服务器建立起联系了
    //如果该套接字有数据向服务器发送,则该套接字就会自动发射一个readyRead信号
    //我们可以将该信号连接到自定义的槽函数中
    connect(s, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
}

//处理readyRead信号的槽函数
void Widget::readyRead_slot()
{
    //删除客户端链表中的无效客户端套接字
    for (int i = 0; i < clientlist.count(); i++)
    {
        //判断套接字的状态
        if(clientlist[i]->state() == 0)
        {
            clientlist.removeAt(i);     //将下标为i的客户端移除
        }
    }

    //遍历所有客户端,查看是哪个客户端发来数据
    for (int i = 0; i < clientlist.count(); i++)
    {
        //返回当前客户端套接字中的可读数据字节个数
        if(clientlist[i]->bytesAvailable() != 0)
        {
            //读取当前客户端的相关数据
            QByteArray msg = clientlist[i]->readAll();

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

            //将接收到的信息,发送给所有客户端
            for (int j = 0; j < clientlist.count(); j++)
            {
                clientlist[j]->write(msg);
            }
        }
    }


}






















客户端

#include "widget.h"
#include "ui_widget.h"

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

    socket = new QTcpSocket(this);

    //如果连接服务器成功,该客户端就会发射一个conneted信号
    //我们可以将该信号连接到自定义的槽函数中
    //由于该连接只需连接一次
    connect(socket, &QTcpSocket::connected, this, &Widget::connected_slot);

    //客户端与服务器连接成功后,如果服务器向客户端发送数据,则该客户端会自动发射一个readyRead信号
    //我们可以将该信号连接到自定义的槽函数中
    connect(socket, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);

    ui->disconnect_btn->setEnabled(false);
    ui->send_btn->setEnabled(false);

    connect(socket, &QTcpSocket::disconnected, this, &Widget::disconnected_slot);

}

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

//连接服务器按钮槽函数
void Widget::on_connect_btn_clicked()
{
    //获取ui界面的信息
    userName = ui->user_edit->text();   //获取用户名
    QString hostName = ui->ip_edit->text();     //主机地址
    quint16 port = ui->port_edit->text().toUInt();  //端口号

    //调用函数连接到主机
    socket->connectToHost(hostName, port);



}

//处理connected信号的槽函数
void Widget::connected_slot()
{
    QMessageBox::information(this, "成功", "连接服务器成功");

    //向服务器发送消息
    QString msg = userName + ":进入聊天室";
    socket->write(msg.toLocal8Bit());

    ui->disconnect_btn->setEnabled(true);
    ui->send_btn->setEnabled(true);
    ui->connect_btn->setEnabled(false);
    ui->port_edit->setEnabled(false);
    ui->ip_edit->setEnabled(false);
    ui->user_edit->setEnabled(false);
}

//处理readyRead信号的槽函数
void Widget::readyRead_slot()
{
    //读取该客户端中的数据
    QByteArray msg = socket->readAll();

    //将数据展示在ui界面
    ui->msg_list->addItem(QString::fromLocal8Bit(msg));
}

//发送按钮对应的槽函数
void Widget::on_send_btn_clicked()
{
    //获取ui界面中编辑的文本内容
    QString m = ui->msg_edit->text();

    //整合要发送的信息
    QString msg = userName + ":" + m;

    //将消息发送给服务器
    socket->write(msg.toLocal8Bit());

    //将消息编辑框中的内容清空
    ui->msg_edit->clear();
}

//处理disconnected信号的槽函数
void Widget::disconnected_slot()
{
    QMessageBox::information(this, "退出", "断开成功");
    ui->disconnect_btn->setEnabled(false);
    ui->send_btn->setEnabled(false);
    ui->connect_btn->setEnabled(true);
    ui->port_edit->setEnabled(true);
    ui->ip_edit->setEnabled(true);
    ui->user_edit->setEnabled(true);
}

//断开服务器按钮槽函数
void Widget::on_disconnect_btn_clicked()
{
    QString msg = userName + ":离开聊天室";
    socket->write(msg.toLocal8Bit());
    socket->disconnectFromHost();
}

void Widget::keyPressEvent(QKeyEvent *event)
{
    qDebug() << "键盘按下了" << event->text() << "键值为:" << event->key();
    if(event->text() == "\r")
    {
        //获取ui界面中编辑的文本内容
        QString m = ui->msg_edit->text();

        //整合要发送的信息
        QString msg = userName + ":" + m;

        //将消息发送给服务器
        socket->write(msg.toLocal8Bit());

        //将消息编辑框中的内容清空
        ui->msg_edit->clear();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值