项目(7)(QT中使用json、 Qt中使用http协议通信、项目中需要用到的mysql表、md5、Qt中md5的使用、base64算法)

QT中使用json

Qt5 新增加了处理 JSON 的类,均以 QJson 开头,在 QtCore 模块中,不需要额外引入其它模块

类说明

QJsonDocument

读写 JSON 文档

QJsonObject

封装 JSON 对象

QJsonArray

封装 JSON 数组

QJsonValue

封装JSON 值

QJsonObject::iterator

用于遍历 QJsonObject 的 STL 风格的非 const 遍历器

QJsonParseError

报告 JSON 处理过程中出现的错误

在内存中有一个json格式字符串,我们想去操作json字符串,应该怎么操作?

头文件

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>

1、首先需要一个JsonDocument类。即将字符串变成JsonDocument对象。

QByteArray——字节数组,在QT里面就相当于一个字符串

QJsonDocument 	fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR)

 

2、利用上面获得的JsonDocument对象调用

  • object方法来将JsonDocument对象转化成json对象
  • array方法来将JsonDocument对象转换成json数组

jaon中有两种类型,数组或者对象,具体参考json、cJSON

 

3、将json对象

通过键值对的键来获取值。

 

 

将json对象存入文件的操作

1、通过JsonDocument将json对象转换成字符串

    // 使用jsonDocument对象加载json字符串
    QJsonDocument doc = QJsonDocument::fromJson(json对象);

2、将字符串存入文件

 

 

整体流程图如下:

 

 

实现的例子——将json数据写入文件

json数据如下

{
    “server”:{
        "IP":"192.168.0.1",
        "PORT":"9000"
    }
}

第一步——创建json对象

    // 创建json对象
    QJsonObject obj;
    //创建子对象
    QJsonObject sub;
    sub.insert("IP", QJsonValue("192.168.1.25"));
    sub.insert("port", "9990");
    //将子对象作为value放在json对象中
    obj.insert("server", QJsonValue(sub));

第二步——构造json对象

    //构造json对象
    QJsonDocument doc(obj);

第三步——将json对象转成字符串

    // 将json对象转换为字符串
    QByteArray data = doc.toJson();

第四步——将字符串写入文件

    // 字符串写入文件
    QFile file("D:\\temp.json");
    file.open(QIODevice::WriteOnly);
    file.write(data);
    file.close();

整体

    // 创建json对象
    QJsonObject obj;
    //创建子对象
    QJsonObject sub;
    sub.insert("IP", QJsonValue("192.168.1.25"));
    sub.insert("port", "9990");
    //将子对象作为value放在json对象中
    obj.insert("server", QJsonValue(sub));

    // 内存中的json数据写入内存
    //构造json对象
    QJsonDocument doc(obj);
    // 将json对象转换为字符串
    QByteArray data = doc.toJson();
    // 字符串写入文件
    QFile file("D:\\temp.json");
    file.open(QIODevice::WriteOnly);
    file.write(data);
    file.close();

 

 

 

例子——使用json类读json文件

    // 读json文件
    QFile file("D:\\temp.json");
    file.open(QIODevice::ReadOnly);
    QByteArray data = file.readAll();
    file.close();

    // 使用jsonDocument对象加载json字符串
    QJsonDocument doc = QJsonDocument::fromJson(data);
    // 判断文件中是json数组还是json对象。是对象,则需要进行解析
    if(doc.isObject())
    {
        QJsonObject obj = doc.object();
        //通过key值将value取出
        QJsonValue value = obj.value("server");
        //如果取出来的值还是一个对象,则继续取值
        if(value.isObject())
        {
            QJsonObject subobj = value.toObject();
            // 通过key来取值。因为我们知道是字符串,所以这里没有判断取出来的是否是字符串
            QString ip = subobj.value("IP").toString();
            QString port = subobj.value("port").toString();
            //打印取出来的结果
            qDebug() << ip << port;
        }
    }

项目中先关的配置文件信息

 

1、服务器端配置文件

	{
		"redis":
		{
			"ip": "127.0.0.1",
			"port": "6379"
		},
		
		"mysql":
		{
			"ip": "127.0.0.1",
			"port": "3306",
			"database": "cloud_disk",
			"user": "root",
			"password": "root"
		},
		
		"dfs_path":
		{
			"client": "./conf/client.conf"
		},
		
		"web_server":
		{
			"ip": "192.168.82.251",
			"port": "80"
		},
		
		"storage_web_server":
		{
			"ip": "192.168.82.251",
			"port": "80"
		}

   }

2、客户端

	{
	    "login": {
	        "pwd": "wqq2b4Ild/w=",
	        "remember": "yes",
	        "user": "Mi/CvL0kLkQ="
	    },
	    "type_path": {
	        "path": "conf/fileType"
	    },
	    "web_server": {
	        "ip": "192.168.1.27",
	        "port": "80"
	    }
	}
	

 

 Qt中使用http协议通信

C/S架构的进行网络通信时,可选协议很多。本项目选择http请求,这样可以支持客户端和网页端两种方式来获取服务器数据  。

QNetworkAccessManager类允许应用程序发送网络请求和接收网络应答。

Network Access API都是围绕着一个QNetworkAccessManager对象构造的,这个对象包含着发送请求的一些通用配置和设置。它包含着代理和缓存的配置,以及和这些事物相关的一些信号,并且应答信号可以作为我们检测一个网络操作的进度。

一个QNetworkAccessManager对于一整个Qt应用程序来说已经足够了!

一旦一个QNetworkAccessManager对象被创建了,那么应用程序就可以使用它在网络上发送请求。它提供了一组标准的函数,可以承载网络请求和一些可选的数据,并且每一个请求返回一个QNetworkReply对象。该返回的对象包含着返回的请求应带的所有数据。

 

头文件

#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>

 

 

QNetworkAccessManager 类——发送get请求或者post请求

  • QNetworkAccessManager将会把它受到的请求排队。并行执行的请求数量是依赖于协议的。
  • 目前,对于桌面平台的HTTP协议,对于一个主机/端口的组合,可6个请求并行执行。

QNetworkRequest类——组织请求头

  • Network Access API的一部分,并且这个类包含着在网络上发送请求的必要信息。
  • 它包含了一个URL和一些可以用来修改请求的附加信息。
  • 将需要发送的http请求协议初始化到QNetworkRequest类中,包括——请求头、数据、url

QNetworkReply 类——处理回复

  • QNetworkAccessManage返回的一个对象, 请求完成之后, 需要删除该对象
  • 我们通过QNetworkAccessManage返回的对象, 读server返回的数据
readyRead()
finished();
readall()

 

 

 

例子

发送get请求访问www.baidu.com:80、获取服务器返回的数据、读取数据并将数据打印

    // 需要一个mamager对象, 做get ,post。一个项目里面有一个QNetworkAccessManager即可
    QNetworkAccessManager* manager = new QNetworkAccessManager(this);
    
    // 准备工作 - 初始化一个QNetworkRequest
    QNetworkRequest res;
    // 设置头 - 浏览器
    res.setHeader(QNetworkRequest::UserAgentHeader,
                  "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36");
    //要发送给谁
    res.setUrl(QUrl("http://www.baidu.com:80"));
    
    //获取服务器返回的数据
    QNetworkReply* reply = manager->get(res);
    // 读服务器回写的数据
    connect(reply, &QNetworkReply::readyRead, this, [=]()
    {
        // 获取返回的头,查看是否是302(重定向)
        QVariant str = reply->header(QNetworkRequest::LocationHeader);
        // 读取所有数据,不包括头
        QByteArray data = reply->readAll();
        qDebug() << data;
        qDebug() << str.toString();
    });

 

 

 

 

项目中需要用到的mysql表

 

数据库基本操作语句

1、创建一个名称为cloud_disk的数据库。

CREATE DATABASE cloud_disk;

 

2. 删除数据库cloud_disk

drop database cloud_disk;

 

3. 使用数据库 cloud_disk

use cloud_disk;

 

 

用户信息表 -  user

 

1、用户信息表字段:

 

id

用户序号,自动递增,主键

name

用户名字

nickname

用户昵称

phone

手机号码

email

邮箱

password

密码

createtime

时间

 

2、sql语句 - 建表

CREATE TABLE user (
    id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR (128) NOT NULL,
    nickname VARCHAR (128) NOT NULL,
    password VARCHAR (128) NOT NULL,
    phone VARCHAR (15) NOT NULL,
    createtime VARCHAR (128),
    email VARCHAR (100),
    CONSTRAINT uq_nickname UNIQUE (nickname),  #指定nickname是唯一的
    CONSTRAINT uq_name UNIQUE (NAME)           #指定name是唯一的
);

 

3、sql语句 - 插入

INSERT INTO USER (name, nickname, password, phone, createtime, email)
VALUES('mike', 'sb', '123456','110','2017-01-11 17:47:30','[email protected]');

 

4、sql语句 - 查询

SELEC id FROM user  WHERE name = "kevin";

 

 

 

文件信息表  -  file_info表

 

1、文件信息表字段

md5

文件md5

file_id

文件id-/group1/M00/00/00/xxx.png

url

文件url 192.168.1.2:80/group1/M00/00/00/xxx.png

size

文件大小, 以字节为单位

type

文件类型: png, zip, mp4……

count

文件引用计数, 默认为1

每增加一个用户拥有此文件,此计数器+1

补充:

md5是文件上传到云盘之后,我们会生成一个md5的哈希值,md5不论文件多大,算出来的字符串长度相同。每个文件对应一个md5.

文件秒上传也是通过md5,。上传文件时,计算其md5,如果md5存在,说明storage中存有该文件,则无需上传。

 

2、sql语句 - 建表

CREATE TABLE file_info (
    md5 VARCHAR (200) NOT NULL PRIMARY KEY,
    file_id VARCHAR (256) NOT NULL,
    url VARCHAR (512) NOT NULL,
    size BIGINT,
    type VARCHAR (20),
    count INT
);

 

3、sql语句 - 更新

UPDATE file_info SET count = 2 WHERE md5 = "bae488ee63cef72efb6a3f1f311b3743";

 

 

 

用户文件列表  -  user_file_list表

 

1、用户文件列表字段

user        

文件所属用户

md5

文件md5

createtime

文件创建时间

filename

文件名字

shared_status

共享状态, 0为没有共享, 1为共享

pv

文件下载量,默认值为0,下载一次加1

 

2、sql语句 - 建表

CREATE TABLE user_file_list (
    user VARCHAR (128) NOT NULL,
    md5 VARCHAR (200) NOT NULL,
    createtime VARCHAR (128),
    filename VARCHAR (128),
    shared_status INT,
    pv INT
);

 

3、查看某个用户的文件列表

SELECT md5 FROM user_file_list WHERE name = "mike";

 

4、查看某个文件的属性

SELECT * FROM file_info WHERE md5 = "bae488ee63cef72efb6a3f1f311b3743";

 

5、设置某个文件是否共享

UPDATE user_file_list SET shared_status = 1 WHERE md5 = "bae488ee63cef72efb6a3f1f311b3743" AND user = 'mike';

 

 

用户文件数量表  -  user_file_count表

 

1、用户文件数量表字段

user                

文件所属用户

count         

拥有文件的数量

 

2、sql语句 - 建表

CREATE TABLE user_file_count (
    user VARCHAR (128) NOT NULL PRIMARY KEY,
    count INT
);

 

3、更新

UPDATE user_file_count SET count = 10 WHERE user = "mike";

 

4、删除

DELETE FROM user_file_count WHERE user = "mike";

 

 

共享文件列表

 

1、共享文件列表字段

user        

文件所属用户

md5

文件md5

createtime

文件共享时间

filename

文件名字

pv

文件下载量,默认值为1,下载一次加1

 

2、建表

CREATE TABLE share_file_list (
    user VARCHAR (128) NOT NULL,
    md5 VARCHAR (200) NOT NULL,
    createtime VARCHAR (128),
    filename VARCHAR (128),
    pv INT
);

 

 

 

 

md5——文件的指纹

Message-Digest Algorithm 5(信息-摘要算法5)

 

MD5算法具有以下特点:

压缩性

  • 任意长度的数据,算出的MD5值长度都是固定的
  • 把一个任意长度的字节串变换成一定长的十六进制数字串

容易计算

  • 从原数据计算出MD5值很容易。

抗修改性

  • 对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。

强抗碰撞

  • md5过程是不可逆
  • 已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

 

md5的应用

  • 文件校验——软件下载站、论坛数据库、系统文件安全等方面
  • 数字证书——互联网通讯中标志通讯各方身份信息的一串数字,提供了一种在Internet上验证通信实体身份的方式
  • 登录验证——操作系统的登陆认证,如Unix、各类BSD系统登录密码

Qt中md5的使用

需要依靠类——QCryptographicHash

头文件

#include <QCryptographicHash>

 

实现代码

// 获取文件数据(这里先用字符串代替)
QByteArray data = "hello, world";
//构造md5对象
QCryptographicHash hash(QCryptographicHash::Md5);
//添加数据
hash.addData(data);
//可以继续添加数据
hash.addData("你好, 世界");
// 计算
QByteArray arry = hash.result();
qDebug() << arry;
//转成16进制。因为md5是由16进制数字组成,不转换,则输出的是字符
arry = arry.toHex();
qDebug() << arry;

 

另一种转化md5的方式

QByteArray arry = QCryptographicHash::hash("hello, world", QCryptographicHash::Md5);
qDebug() << arry.toHex();

 

补充:文件内容相同,如果编码方式不同,则md5不同

 

 

 

base64算法

Base64是一种用64个字符来表示任意二进制数据的方法。

 

1、为什么要用base64编码

  • 在网络上交换数据时,比如说从A地传到B地,往往要经过多个路由设备,由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的。
  • 把数据先做一个Base64编码,统统变成可见字符,这样出错的可能性就大降低了
  • 很多场景下的数据传输要求数据只能由简单通用的字符组成,比如HTTP协议要求请求的首行和请求头都必须是ASCII编码

 

2、使用base64能做什么

  • 所有的二进制文件,都可以因此转化为可打印的文本编码,使用文本软件进行编辑
  • 能够对文本进行简单的加密

 

3、算法描述

  • 将字符串分隔成3个字节为一组,每组八位的几组小串
  • 把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24)
  • 在6位的前面补两个0,形成8位一个字节的形式
  • 如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'=', 表示补了多少字节,解码的时候,会自动去掉。

 

 

Qt中使用base64

需要用到类——QByteArray

实现代码

// 编码
QByteArray base = "你好, 世界";
base = base.toBase64();
qDebug() << base;

// 解码
base= QByteArray::fromBase64(base);
qDebug() << base.data();

 

猜你喜欢

转载自blog.csdn.net/qq_29996285/article/details/87885737