图片服务器
项目意图:在写博客过程中,上传图片时,看到下面这个窗口有了想法自己能否做出类似的图片服务器?
存储图片的服务器(图床)
项目描述:实现一个HTTP服务器,然后用这个服务器来存储图片,针对每个图片提供一个唯一的url,有了这个url之后就可以借助它把图片展示到其他网页上。
实现环境:Centos7.2
核心需求
- 上传一个图片(得到一个url)
- 根据图片的url访问图片(获取图片内容)
- 获取某个图片的属性(png/jpg/user)
- 删除等操作
模块划分
1,数据存储模块
数据库(MySQL)设计
数据库中只需要一张表,表头信息如下:
create table image_table(
image_id int,
image_name varchar(256),
size_int,
upload_time varchar(50),
type varchar(50),
path varchar(1024),
md5 varchar(50),
)
md5:校验和
1,不管啥样的字符串,最终的到的md5值都是固定长度
2,如果一个字符串,内容稍有变化,得到的md5值差异很大
3,通过原字符串计算md5很容易,但是拿到md5还原原串理论上不可能
- md5这个字段用来进行校验图片内容正确性
- 上传图片之后,服务器就可以计算一个该图片的md5值
- 后续用户下载图片的时候,也能获取到该图片的md5,用户可以吧自己计算的md5和服务器计算的md5对比,就知道自己的图片是否下载正确了。
针对图片内容,可以直接存在磁盘上。
以下是数据库表的代码:
db.sql
create database if not exists image_system;
use image_system;
drop table if exists image_table;
create table image_table(
image_id int not null primary key auto_increment,
image_name varchar(256),
size int,
upload_time varchar(50),
md5 varchar(128),
type varchar(128),
path varchar(1024)
);
insert into image_table values(null, 'test.png', 1024, '2019/08/16', 'aaaabbbbbccccc', 'png', 'data/test.png')
使用MySQL C API操作数据库
安装MySQL API:
yum install mysql++-devel.x86_64
代码中使用时需要连接上MySQL提供的库
-L /usr/lib64/mysql -lmysqlclient
数据库插入数据
mysql_insert.cc
#include <cstdio>
#include <cstdlib>
#include <mysql/mysql.h>
int main() {
// 使用 mysql API 来操作数据库了
// 1. 先创建一个 mysql 的句柄
MYSQL* mysql = mysql_init(NULL);
// 2. 拿着句柄和数据库建立链接
if (mysql_real_connect(mysql, "127.0.0.1", "root", "", "image_system", 3306, NULL, 0) == NULL) {
// 数据库链接失败
printf("连接失败! %s\n", mysql_error(mysql));
return 1;
}
// 3. 设置编码格式
mysql_set_character_set(mysql, "utf8");
// 4. 拼接 SQL 语句
char sql[4096] = {0};
sprintf(sql, "insert into image_table values(null, 'test.png', 1024, '2019/08/16', 'abcdef', 'png', 'data/test.png')");
// 5. 执行 sql 语句, 负责了客户端给服务器发送数据的过程
int ret = mysql_query(mysql, sql);
if (ret != 0) {
printf("执行 sql 失败! %s\n", mysql_error(mysql));
return 1;
}
// 6. 关闭句柄
mysql_close(mysql);
return 0;
}
数据库查找数据
mysql_select.cc
#include <cstdio>
#include <cstdlib>
#include <mysql/mysql.h>
int main() {
// 使用 mysql API 来操作数据库了
// 1. 先创建一个 mysql 的句柄
MYSQL* mysql = mysql_init(NULL);
// 2. 拿着句柄和数据库建立链接
if (mysql_real_connect(mysql, "127.0.0.1", "root", "", "image_system", 3306, NULL, 0) == NULL) {
// 数据库链接失败
printf("连接失败! %s\n", mysql_error(mysql));
return 1;
}
// 3. 设置编码格式
mysql_set_character_set(mysql, "utf8");
// 4. 拼接 SQL 语句
char sql[4096] = {0};
sprintf(sql, "select * from image_table");
// 5. 执行 sql 语句, 负责了客户端给服务器发送数据的过程
int ret = mysql_query(mysql, sql);
if (ret != 0) {
printf("执行 sql 失败! %s\n", mysql_error(mysql));
return 1;
}
// 6. 获取结果集合
MYSQL_RES* result = mysql_store_result(mysql);
int rows = mysql_num_rows(result);
int cols = mysql_num_fields(result);
for (int i = 0; i < rows; ++i) {
MYSQL_ROW row = mysql_fetch_row(result);
for (int j = 0; j < cols; ++j) {
printf("%s\t", row[j]);
}
printf("\n");
}
// 7. 释放结果集合
mysql_free_result(result);
// 8. 关闭句柄
mysql_close(mysql);
return 0;
}
makefile
.PHONY:all
all:mysql_select mysql_insert
mysql_insert:mysql_insert.cc
g++ $^ -o $@ -L/usr/lib64/mysql -lmysqlclient
mysql_select:mysql_select.cc
g++ $^ -o $@ -L/usr/lib64/mysql -lmysqlclient
.PHONY:clean
cl