<3>[QTCN]图片网络传输工具(客户端)

简介: 说明:图片网络传输工具(客户端)亮点:图片网络传输

参考

<6>[QTCN]图片网络传输工具(客户端)

说明:图片网络传输工具(客户端)

亮点:图片网络传输

实现

PictureTcpClient.pro

QT       += network
AI 代码解读

main.cpp

#include "picturetcpclient.h"
#include <QApplication>
#include<QFont>
int main(int argc, char *argv[])
{
   
    QApplication a(argc, argv);
    PictureTcpClient w;
    QFont font;
    font.setPixelSize(25);
    w.setFont(font);
    w.show();
    return a.exec();
}
AI 代码解读

picturetcpclient.h


#ifndef PICTURETCPCLIENT_H
#define PICTURETCPCLIENT_H

#include <QWidget>
#include<QtNetwork>
#include<QTcpSocket>
#include<QFileDialog>
#include<QMessageBox>
#pragma execution_character_set("utf-8")

QT_BEGIN_NAMESPACE
namespace Ui {
    class PictureTcpClient; }
QT_END_NAMESPACE

class PictureTcpClient : public QWidget
{
   
    Q_OBJECT

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

    void InitTcp();
    void ChangeEnable(bool isEnable);
    void ConnectToServer();     //连接服务器
    void SendData();            //发送数据
    QStringList GetFileNames(QString filter);   //获取打开对话框中指定格式的文件列表
    void DelayTime(int ms);                     //延时等待功能
    QByteArray GetPicData(QString fromPic);

private slots:
    void on_btnConnect_clicked();

    void on_btnDisConnect_clicked();

    void on_btnSend_clicked();

    void on_btnSelectImg_clicked();

    void on_btnClear_clicked();

    void on_btnSendImg_clicked();

    void conSuc();              //连接成功
    void ReadData();            //读取数据
    void DisplayError(QAbstractSocket::SocketError);

private:
    Ui::PictureTcpClient *ui;

    QTcpSocket *m_tcpClient;
};

#endif // PICTURETCPCLIENT_H
AI 代码解读

picturetcpclient.cpp


#include "picturetcpclient.h"
#include "ui_picturetcpclient.h"
#pragma execution_character_set("utf-8")

PictureTcpClient::PictureTcpClient(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::PictureTcpClient)
{
   
    ui->setupUi(this);
    this->setWindowIcon(QIcon(":/1.ico"));
    this->setWindowTitle("图片网络传输工具(客户端)");
    this->ChangeEnable(false);
    this->InitTcp();
}

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

void PictureTcpClient::InitTcp()
{
   
    m_tcpClient = new QTcpSocket(this);
    m_tcpClient->abort();               //中断已有的链接
    connect(m_tcpClient,SIGNAL(readyRead()),this,SLOT(ReadData()));
    connect(m_tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),\
            this,SLOT(DisplayError(QAbstractSocket::SocketError)));

    //该信号在调用connectToHost()并成功建立连接之后发出。
    connect(m_tcpClient, SIGNAL(connected()),this, SLOT(conSuc()));
}

void PictureTcpClient::ChangeEnable(bool isEnable)
{
   
    ui->btnConnect->setEnabled(!isEnable);
    ui->btnDisConnect->setEnabled(isEnable);
    ui->btnSend->setEnabled(isEnable);
    ui->btnSendImg->setEnabled(isEnable);
}

//连接服务器
void PictureTcpClient::ConnectToServer()
{
   
    m_tcpClient->abort();
    m_tcpClient->connectToHost(ui->txtIP->text(),ui->txtPort->text().toInt());
}

//连接成功
void PictureTcpClient::conSuc()
{
   
    ui->labInfo->setText("提示:连接成功");
    this->ChangeEnable(true);
}

//发送数据
void PictureTcpClient::SendData()
{
   
    // 获取 QTextEdit 中的纯文本内容,转换为Latin-1单字节编码的字节数组
    m_tcpClient->write(ui->txtSendData->toPlainText().toUtf8());
}

//读取数据
void PictureTcpClient::ReadData()
{
   
    QByteArray read=m_tcpClient->readAll();
    if (!read.isEmpty())
    {
   
        ui->txtGetData->append(QString::fromUtf8(read));
    }
}

void PictureTcpClient::DisplayError(QAbstractSocket::SocketError)
{
   
    ui->labInfo->setText(QString("提示:连接失败,原因(%1)").arg(m_tcpClient->errorString()));
    this->ChangeEnable(false);
}

//获取打开对话框中指定格式的文件列表
QStringList PictureTcpClient::GetFileNames(QString filter)
{
   
    QStringList fileNames;
    fileNames=QFileDialog::getOpenFileNames(this,"选择文件",QCoreApplication::applicationDirPath(),filter);
    if (fileNames.isEmpty())
    {
   
        return QStringList();
    }
    else
    {
   
        return fileNames;
    }
}

//延时等待功能
void PictureTcpClient::DelayTime(int ms)
{
   
    QTime t=QTime::currentTime().addMSecs(ms);//当前时间的基础上增加ms毫秒,得到一个目标时间点t
    while(QTime::currentTime()<t)
    {
   /*处理当前线程的事件队列,并等待最多100毫秒来接收新的事件。
      *处理所有类型的事件,包括定时器事件、绘图事件等
      *通过不断处理事件,可以确保程序在等待期间仍然能够响应其他事件,以避免程序无响应或阻塞*/
        QCoreApplication::processEvents(QEventLoop::AllEvents,100);
    }
}

QByteArray PictureTcpClient::GetPicData(QString fromPic)
{
   
    QImage img(fromPic);
    // 保存图像数据到 QByteArray
    QByteArray ba;
    QBuffer buf(&ba);
    buf.open(QIODevice::WriteOnly);
    img.save(&buf,"JPG");               //按照JPG解码保存数据
    buf.close();

    QByteArray cc=qCompress(ba,1);      // 对图像数据进行压缩

    QByteArray hh;
    hh=cc.toBase64();                   //获取Base64数据
    return hh;
}


void PictureTcpClient::on_btnConnect_clicked()
{
   
    this->ConnectToServer();
}


void PictureTcpClient::on_btnDisConnect_clicked()
{
   
    m_tcpClient->disconnectFromHost();      //断开QTcpSocket对象与远程主机的连接的函数
    ui->labInfo->setText(tr("提示:断开连接"));
    this->ChangeEnable(false);
}


void PictureTcpClient::on_btnSend_clicked()
{
   
    this->SendData();
}


void PictureTcpClient::on_btnSelectImg_clicked()
{
   
   ui->listWidget->addItems(this->GetFileNames("图片文件(*.jpg)"));
}


void PictureTcpClient::on_btnClear_clicked()
{
   
   if (ui->listWidget->count()>0)
        ui->listWidget->clear();
}


void PictureTcpClient::on_btnSendImg_clicked()
{
   
   if (ui->listWidget->count()<=0)                      //没有图片发送则返回
        return;
   QListWidgetItem *myitem;
   int intervalTime=ui->txtTime->text().toInt();
   qDebug()<<"图片 ="<<ui->listWidget->count();
   for (int i=0;i<ui->listWidget->count();i++)
   {
   
        qDebug()<<"i="<<i;
        myitem=ui->listWidget->item(i);
        QByteArray myPicData=this->GetPicData(myitem->text());
        if (ui->rbtnJY->isChecked())                    //数据校验
        {
   
            QByteArray ba;
            QDataStream out(&ba,QIODevice::WriteOnly);  //使用数据流写入数据
            out.setVersion(QDataStream::Qt_4_7);        //设置数据流版本,客户端和服务器端使用版本要相同
            /*预留两个字节的空间来存放文件大小信息
             * 将0的quint16类型的数据写入到数据流中*/
            out<<(quint16)0;                            //放置文件大小信息
            out<<myPicData;                             //将实际的文件数据写入到数据流中
            out.device()->seek(0);                      //将数据流的位置指针移动到起始位置。可以在起始位置再次写入文件大小信息
            /*文件数据的大小减去预留的两个字节后的值*/
            out<<(quint16)(ba.size()-sizeof(quint16));  //将实际的文件大小信息写入到数据流中
            myPicData.clear();
            myPicData=ba;
        }
        m_tcpClient->write(myPicData);
        this->DelayTime(intervalTime);
   }
    QMessageBox::information(this,"提示","恭喜你!发送图片完成!");
}
AI 代码解读

picturetcpclient.ui

image.png

效果

演示.gif

源码

[Gitee:03PictureTcpClient[QTCN]图片网络传输工具(客户端)]

模糊知识点

  1. 设置数据流版本,放置文件大小信息
QByteArray ba;
QDataStream out(&ba,QIODevice::WriteOnly);  //使用数据流写入数据
out.setVersion(QDataStream::Qt_4_7);        //设置数据流版本,客户端和服务器端使用版本要相同
/*预留两个字节的空间来存放文件大小信息
 * 将0的quint16类型的数据写入到数据流中*/
out<<(quint16)0;                            //放置文件大小信息
out<<myPicData;                             //将实际的文件数据写入到数据流中
out.device()->seek(0);                      //将数据流的位置指针移动到起始位置。可以在起始位置再次写入文件大小信息
/*文件数据的大小减去预留的两个字节后的值*/
out<<(quint16)(ba.size()-sizeof(quint16));  //将实际的文件大小信息写入到数据流中
AI 代码解读
  1. 返回值QByteArray,在#pragma execution_character_set("utf-8")编程环境下,使用QString::toUtf8()

toUtf8()函数将字符串转换为UTF-8编码格式。UTF-8是一种可变长度的Unicode编码,它可以表示世界上几乎所有的字符,并且与ASCII兼容。UTF-8编码在国际化和多语言支持方面非常常用,因为它可以表示各种语言的字符。

toLatin1()函数将字符串转换为Latin1编码格式。Latin1,也称为ISO-8859-1,是一个简单的单字节编码,它可以表示西欧语言中的字符。使用Latin1编码时,每个字符占用一个字节。

区别:

编码范围:toUtf8()函数能够表示更广泛的字符范围,包括Unicode字符集中的所有字符,而toLatin1()函数只能表示Latin1字符集中的字符。

字节长度:UTF-8编码是一种可变长度的编码方案,一个字符可能由1到4个字节组成,而Latin1编码是一种固定长度的编码方案,每个字符只占用一个字节。

如果你的应用程序需要处理多语言、国际化或Unicode字符集中的字符,那么通常建议使用toUtf8()函数。
如果你只需要处理简单的单字节字符,比如英文字符或西欧语言字符,那么使用toLatin1()函数可能更为合适。

需要注意的是,在进行编码转换时,要确保目标编码能够正确表示源字符串中的所有字符。
如果源字符串包含了目标编码中不支持的字符,转换结果可能会出现乱码或数据丢失的情况。

目录
打赏
0
0
0
0
1
分享
相关文章
|
19天前
|
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
68 20
Linux(openwrt)下iptables+tc工具实现网络流量限速控制(QoS)
通过以上步骤,您可以在Linux(OpenWrt)系统中使用iptables和tc工具实现网络流量限速控制(QoS)。这种方法灵活且功能强大,可以帮助管理员有效管理网络带宽,确保关键业务的网络性能。希望本文能够为您提供有价值的参考。
108 28
FireCrawl:开源 AI 网络爬虫工具,自动爬取网站及子页面内容,预处理为结构化数据
FireCrawl 是一款开源的 AI 网络爬虫工具,专为处理动态网页内容、自动爬取网站及子页面而设计,支持多种数据提取和输出格式。
439 19
FireCrawl:开源 AI 网络爬虫工具,自动爬取网站及子页面内容,预处理为结构化数据
深入解析:Linux网络配置工具ifconfig与ip命令的全面对比
虽然 `ifconfig`作为一个经典的网络配置工具,简单易用,但其功能已经不能满足现代网络配置的需求。相比之下,`ip`命令不仅功能全面,而且提供了一致且简洁的语法,适用于各种网络配置场景。因此,在实际使用中,推荐逐步过渡到 `ip`命令,以更好地适应现代网络管理需求。
46 11
浅析Kismet:无线网络监测与分析工具
Kismet是一款开源的无线网络监测和入侵检测系统(IDS),支持Wi-Fi、Bluetooth、ZigBee等协议,具备被动监听、实时数据分析、地理定位等功能。广泛应用于安全审计、网络优化和频谱管理。本文介绍其安装配置、基本操作及高级应用技巧,帮助用户掌握这一强大的无线网络安全工具。
110 9
浅析Kismet:无线网络监测与分析工具
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
30 0
Nping工具详解:网络工程师的瑞士军刀
### Nping工具详解:网络工程师的瑞士军刀 Nping是Nmap项目的一部分,支持TCP、UDP、ICMP和ARP等多种协议,用于生成和分析网络数据包。它提供灵活的命令行界面,适用于网络探测、安全测试和故障排除。本文介绍Nping的基础与高级用法,包括发送不同类型的网络请求、自定义TCP标志位、路由跟踪等,并通过实战案例展示其应用。掌握Nping有助于更好地理解和管理网络环境。 (239字符)
97 9
【Azure Cloud Service】在Windows系统中抓取网络包 ( 不需要另外安全抓包工具)
通常,在生产环境中,为了保证系统环境的安全和纯粹,是不建议安装其它软件或排查工具(如果可以安装,也是需要走审批流程)。 本文将介绍一种,不用安装Wireshark / tcpdump 等工具,使用Windows系统自带的 netsh trace 命令来获取网络包的步骤
109 32
访问控制列表(ACL)是网络安全管理的重要工具,用于定义和管理网络资源的访问权限。
访问控制列表(ACL)是网络安全管理的重要工具,用于定义和管理网络资源的访问权限。ACL 可应用于路由器、防火墙等设备,通过设定规则控制访问。其类型包括标准、扩展、基于时间和基于用户的ACL,广泛用于企业网络和互联网安全中,以增强安全性、实现精细管理和灵活调整。然而,ACL 也存在管理复杂和可能影响性能的局限性。未来,ACL 将趋向智能化和自动化,与其他安全技术结合,提供更全面的安全保障。
226 4
OSPF路由汇总:优化网络的强大工具
OSPF路由汇总:优化网络的强大工具
106 1

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等