Project:图片服务器(图床)

本文介绍了一个使用C++实现的图片服务器项目,实现了上传、查看、删除图片的功能,采用RESTful API设计,数据库存储使用MySQL,通过cpp-httplib框架搭建服务器,并进行了详细的测试。涉及到的技术包括MySQL C API、jsoncpp、HTTP协议和MD5校验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

图片服务器

项目意图:在写博客过程中,上传图片时,看到下面这个窗口有了想法自己能否做出类似的图片服务器?

存储图片的服务器(图床)

项目描述:实现一个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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值