QT实战网络编程客户端和服务器收发文件

QTcpServer+QTcpSocket 学习开启

  • 简介
  • 服务器头文件
  • 服务器源文件
  • 服务器UI设计
  • 客户端头文件
  • 客户端源文件
  • 客户端UI设计
  • 展示效果
  • 总结

简介

废话不多说,实现客户端和服务器收发文件,就是吹牛,学会如何搭建成功,基于局域网实现!
记得添加network到 .pro工程文件

QT实战网络编程客户端和服务器收发文件_第1张图片

服务器头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 
#include
#include


//在添加服务器和套接字头文件之前,需要在.pro加上network库
#include
#include

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:

    void on_pushButton_clicked();
    void on_pushButton_2_clicked();
    void RecvData();
    void  connectprocess();
    void closeconnect();

    void on_pushButton_3_clicked();

private:
    Ui::MainWindow *ui;
    QTextCodec *codec;
    QTcpServer* my_server;//服务器指针
    QTcpSocket* my_tcp;//套接字指针
    QString filename;
};
#endif // MAINWINDOW_H

服务器源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QDebug"
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    codec = QTextCodec::codecForName("GBK");//解决ui显示乱码
    QTextCodec::setCodecForLocale(codec);
    setWindowTitle(codec->toUnicode("TCP_服务器"));//这样就不会显示乱码了


    //申请服务器空间资源 【第一步】
    my_server = new QTcpServer(this);//指定其父this
    //发送者  发送信号  接收者  接收槽函数 【第二步】
    connect(my_server, SIGNAL(newConnection()),this,SLOT(connectprocess()));

}

MainWindow::~MainWindow()
{
    delete ui;
}
//开启服务器【第三步】
void MainWindow::on_pushButton_clicked()
{
    //设置监听
    quint16 port =QString(ui->lineEdit->text()).toUShort();//获取端口号,人为输入
    my_server->listen(QHostAddress::Any,port);//自动获取主机地址【电脑IPV4地址就是】
    ui->pushButton->setEnabled(false);//设置按钮不可点击
    ui->textEdit->append(codec->toUnicode("服务器监听开启中,等待连接"));
}
//发送数据 【第四步】
void MainWindow::on_pushButton_2_clicked()
{
    //获取文本编辑框中的文本
    QString str =ui->textEdit_2->toPlainText();
    //发送到客户端
    my_tcp->write(str.toUtf8());
    ui->textEdit_2->clear();//清空
}
//接收数据 【第四步】
void MainWindow::RecvData()
{
    QString recv = my_tcp->readAll();//接收全部数据
    ui->textEdit->append("form Client: "+codec->toUnicode(recv.toUtf8()));//显示在 接收框
}

//服务器连接处理
void MainWindow::connectprocess()
{
    //当有客户端连接进来时,或者这个用于双方通信的套接字
    my_tcp = my_server->nextPendingConnection();
    ui->textEdit->append("Client form connect");
    QHostAddress addr = my_server->serverAddress();
    quint16 port = my_server->serverPort();
    ui->textEdit->append(addr.toString().toUtf8());
    ui->textEdit->append("Port :"+QString::number(port));

//===================【为什么放这里,因为要先连接才能进行数据的读写和断开等】
    //接收数据,有数据会触发readyRead
    connect(my_tcp,SIGNAL(readyRead()),this,SLOT(RecvData()));
    //客户端关闭了连接,会触发信号disconnected
      connect(my_tcp,SIGNAL(disconnected()),this,SLOT(closeconnect()));

}
//客户端关闭了连接
void MainWindow::closeconnect()
{
    //客户端离开了连接
    ui->textEdit->append(codec->toUnicode("客户端离开了你"));
    my_tcp->deleteLater();//手动删除套接字
}

//发送文件
void MainWindow::on_pushButton_3_clicked()
{
    filename = QFileDialog::getOpenFileName();//文件对话框
    ui->textEdit->append(codec->toUnicode(filename.toUtf8()));

    QFile f(filename);
    if(!f.open(QIODevice::ReadWrite))
    {
        ui->textEdit->append("file open fail");
        return;
    }
    QByteArray filedata = f.readAll();//获取文件全部内容
    //发送给客户端
    my_tcp->write(filedata);
}

服务器UI设计

背景设置这些不是本次的重点
QT实战网络编程客户端和服务器收发文件_第2张图片

客户端头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include
#include

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::MainWindow *ui;
    QTcpSocket *my_tcp;
    QTextCodec *codec;
};
#endif // MAINWINDOW_H

客户端源文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    codec = QTextCodec::codecForName("GBK");//解决ui显示乱码
    QTextCodec::setCodecForLocale(codec);
    setWindowTitle(codec->toUnicode("TCP_客户端"));//这样就不会显示乱码了

      // 创建通信的套接字对象
        my_tcp = new QTcpSocket(this);
        // 检测是否和服务器是否连接成功了【1】
          connect(my_tcp, &QTcpSocket::connected, this, [=]()
          {
              ui->textEdit->append(codec->toUnicode("恭喜, 连接服务器成功!!!"));
          });

        // 检测服务器是否回复了数据【2】
        connect(my_tcp, &QTcpSocket::readyRead, [=]()//===================这里采用另一种写法
        {
            // 接收服务器发送的数据
            QByteArray recvMsg = my_tcp->readAll();
            ui->textEdit->append(codec->toUnicode("来自服务器说: ") + codec->toUnicode(recvMsg));
        });

            // 检测服务器是否和客户端断开了连接【3】
            connect(my_tcp, &QTcpSocket::disconnected, this, [=]()
            {
                ui->textEdit->append(codec->toUnicode("服务器已经断开了连接, ..."));
                ui->pushButton->setEnabled(true);//此时连接服务器按钮使能,可以再次连接
                ui->pushButton_3->setEnabled(false);//此时断开连接不能点击
            });

}

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

//连接服务器
void MainWindow::on_pushButton_clicked()
{
         //获取IP地址
        QString ip = ui->lineEdit_2->text();
        unsigned short port = ui->lineEdit->text().toInt();//获取端口号
        // 连接服务器
        my_tcp->connectToHost(QHostAddress(ip), port);//连接到服务器,通过ip和port
        ui->pushButton->setEnabled(false);
        ui->pushButton_3->setEnabled(true);
}

//断开连接
void MainWindow::on_pushButton_3_clicked()
{
        my_tcp->close();
        ui->pushButton->setEnabled(true);//连接服务器哦
        ui->pushButton_3->setEnabled(false);//断开连接
}

//发送数据
void MainWindow::on_pushButton_2_clicked()
{
        QString sendMsg = ui->textEdit_2->toPlainText();
        my_tcp->write(sendMsg.toUtf8());
        ui->textEdit->append(codec->toUnicode("客户端Say: ") + codec->toUnicode(sendMsg.toUtf8()));
        ui->textEdit_2->clear();//清空发送数据框
}

客户端UI设计

QT实战网络编程客户端和服务器收发文件_第3张图片

展示效果

由于缺少gif工具
具体效果各自实现
QT实战网络编程客户端和服务器收发文件_第4张图片

总结

古天将降于斯人也,必先苦其心志,饿其体肤,劳其筋骨
qDebug<<奥利给<

你可能感兴趣的:(Qt5,界面开发工程师课程,服务器,qt,Qt网络编程,QTcpServer,QTcpSocket)