目录
[3.1 架构设计](#3.1 架构设计)
[3.2 核心模块介绍](#3.2 核心模块介绍)
[3.3 系统流程图](#3.3 系统流程图)
[4.1 用户注册与登录](#4.1 用户注册与登录)
[4.1.1 注册功能实现](#4.1.1 注册功能实现)
[4.1.2 登录功能实现](#4.1.2 登录功能实现)
[4.2 商品搜索](#4.2 商品搜索)
[4.2.1 关键词模糊查询](#4.2.1 关键词模糊查询)
[4.2.2 ID精确查询](#4.2.2 ID精确查询)
[4.2.3 动态页面生成](#4.2.3 动态页面生成)
[4.3 资源加载与 URL 编解码](#4.3 资源加载与 URL 编解码)
[4.3.1 静态资源加载](#4.3.1 静态资源加载)
[4.3.2 URL 编解码](#4.3.2 URL 编解码)
[4.4 异常处理](#4.4 异常处理)
[4.5 结果展示](#4.5 结果展示)
[5.1 项目亮点](#5.1 项目亮点)
[5.2 技术难点](#5.2 技术难点)
[6.1 项目总结](#6.1 项目总结)
[6.2 未来优化方向](#6.2 未来优化方向)
在数字化购物场景中,用户对商品信息的快速检索、精准定位需求日益迫切。传统电子商城常存在查询入口分散、检索效率低、交互繁琐等问题,影响用户体验。为此,我基于 C 语言、HTTP 协议与 SQLite 数据库,开发了一款轻量高效的电子商城信息查询系统,整合用户注册登录、商品模糊搜索、ID 精确查询、详情展示等核心功能。本文将详细分享项目的设计思路、核心实现与技术亮点。
技术栈:C语言、HTTP/1.1、TCP、SQLite3、HTML
一、项目核心目标
- 解决商品查询效率低、交互不便捷的痛点,提供统一查询入口
- 实现完整的用户身份验证流程(注册 + 登录)
- 支持商品关键词模糊搜索与 ID 精确查询,快速定位目标商品
- 动态生成搜索结果页与商品详情页,优化前端展示
- 保证系统轻量性与稳定性,适配基础服务器环境
二、技术选型解析
| 技术方向 | 选型 | 选型理由 |
|---|---|---|
| 后端开发 | C 语言 | 接近底层、执行效率高,适合实现轻量 HTTP 服务器,无冗余依赖 |
| 数据库 | SQLite | 轻量级文件型数据库,无需独立服务进程,适配小型应用存储需求,支持 SQL 标准 |
| 网络协议 | HTTP/1.1 | 基于 TCP 协议,浏览器原生支持,简化客户端与服务器交互 |
| 前端展示 | HTML + 原生 CSS | 静态模板 + 动态数据拼接,无需复杂前端框架,降低开发成本 |
| 辅助工具 | URL 编解码模块 | 处理中文等特殊字符,保证参数传输正确性 |
| 开发工具 | GCC 编译器、SQLite3 客户端 | 跨平台兼容,调试便捷 |
三、系统整体设计
3.1 架构设计
采用分层架构与模块化设计,从下至上分为数据库层、核心功能层、网络交互层,整体架构如下:
系统整体架构图
3.2 核心模块介绍
每个模块各司其职,通过函数调用实现数据流转,关键模块与代码对应关系如下:
| 模块名称 | 核心功能 | 对应代码文件 / 函数 |
|---|---|---|
| 请求解析模块 | 提取 HTTP 请求中的方法、URL、参数 | 01ser.c / parse_http_request |
| 路由分发模块 | 根据 URL 路径分发至对应业务模块 | 01ser.c / main 函数 URL 判断逻辑 |
| 用户管理模块 | 注册验证、登录校验 | 01ser.c / handle_register、handle_login |
| 商品查询模块 | 模糊搜索、ID 精确查询 | 02sql_search.c / search_goods、handle_detail |
| 页面生成模块 | 动态拼接 HTML 页面 | 02sql_search.c / search_result、detail_result |
| 资源加载模块 | 加载 HTML / 图片静态资源 | 01ser.c / send_head、send_file |
| URL 编解码模块 | 处理特殊字符传输 | url2.c / urlencode、urldecode |
| 数据库操作模块 | 数据库连接、查询、插入 | 01ser.c / 02sql_search.c / sqlite3_open / exec |
3.3 系统流程图
系统流程图
四、核心功能实现详解
4.1 用户注册与登录
4.1.1 注册功能实现
流程:用户访问注册页→填写信息提交→后端解析参数→验证合法性→数据库写入→返回结果
- 关键步骤1:参数解析与解码
从 URL 中提取用户名、密码、确认密码,通过 urldecode 处理中文等特殊字符
cpp
char *params = strchr(url, '?');
params++; // 跳过问号
// 解析username、userpass、confirmpass参数
char *param = strtok(params, "&");
while (param)
{
char *key = param;
char *value = strchr(param, '=');
if (value)
{
*value = '\0';
value++;
urldecode(value); // 解码特殊字符
if (0 == strcmp(key, "username")) strncpy(username, value, sizeof(username)-1);
else if (0 == strcmp(key, "userpass")) strncpy(userpass, value, sizeof(userpass)-1);
else if (0 == strcmp(key, "confirmpass")) strncpy(confirmpass, value, sizeof(confirmpass)-1);
}
param = strtok(NULL, "&");
}
- 关键步骤 2:合法性验证
验证密码一致性,查询数据库判断用户名是否已存在
cpp
// 验证密码一致性
if (strcmp(userpass, confirmpass) != 0)
{
send_file(conn, "./07error.html", FILE_HTML);
return;
}
// 查询用户名是否存在
const char *query_sql = "select name from user where name = ?;";
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
if (sqlite3_step(stmt) == SQLITE_ROW)
{
// 用户名已存在,返回错误页
sqlite3_finalize(stmt);
sqlite3_close(db);
send_file(conn, "./08error.html", FILE_HTML);
return;
}
- 关键步骤 3:数据库插入
验证通过后,将用户信息写入 user.db,返回注册成功页
cpp
// 插入新用户
const char *insert_sql = "insert into user values (?, ?);";
// 绑定用户名和密码
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, userpass, -1, SQLITE_STATIC);
//注册成功
if (sqlite3_step(stmt) == SQLITE_DONE)
{
send_file(conn, "./09success.html", FILE_HTML);
}
4.1.2 登录功能实现
核心逻辑:匹配用户名与密码,验证通过跳转至搜索页
cpp
// 查询数据库中的密码
const char *query_sql = "select password from user where name = ?;";
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
if (sqlite3_step(stmt) == SQLITE_ROW)
{
const char *db_pass = (const char *)sqlite3_column_text(stmt, 0);
if (db_pass && strcmp(userpass, db_pass) == 0)
{
// 密码匹配,跳转至搜索页
send_file(conn, "./02search.html", FILE_HTML);
return;
}
}
// 验证失败,返回错误页
send_file(conn, "./05error.html", FILE_HTML);
4.2 商品搜索
4.2.1 关键词模糊查询
用户主动操作,核心查询方式
适用场景:用户输入商品名称关键词(如 "三星"),匹配所有名称包含该关键词的商品。
- 关键实现:search_goods 函数中构造模糊查询 SQL:
cpp
// 非纯数字关键词,按商品名称模糊查询
snprintf(sql_cmd, sizeof(sql_cmd),
"select goods_name, goods_img, goods_id, goods_desc, market_price, shop_price "
"from goods where goods_name like '%%%s%%';",
keyword);
- 结果处理:通过 callback 函数将查询结果封装到 SearchResult 结构体,包含商品名称、图片、价格等信息。
cpp
SearchResult *result = (SearchResult *)data;
result->products = (Product *)realloc(result->products, (result->count + 1) * sizeof(Product));
result->products[result->count].goods_name = strdup(argv[0]);
result->products[result->count].goods_img = strdup(argv[1]);
result->products[result->count].goods_id = strdup(argv[2]);
result->products[result->count].goods_desc = strdup(argv[3]);
result->products[result->count].market_price = strdup(argv[4]);
result->products[result->count].shop_price = strdup(argv[5]);
4.2.2 ID精确查询
系统内部逻辑,仅用于详情页生成
适用场景:用户点击搜索结果中的商品,通过商品 ID 精准获取详情。
- 关键实现:
- 从 URL 提取商品 ID(如/detail_19 提取 ID 为 19);
- 设置 search_flag=1,触发精确查询模式:
cpp
if (is_all_digit(keyword) && search_flag == 1)
{
// 纯数字ID,精确查询
snprintf(sql_cmd, sizeof(sql_cmd),
"select goods_name, goods_img, goods_id, goods_desc, market_price, shop_price "
"from goods where goods_id = %s;",
keyword);
}
4.2.3 动态页面生成
查询结果通过替换 HTML 模板占位符生成动态页面
- 搜索结果页:读取 03goods.html 模板,替换 {{GOODS_NAME}} 为商品列表 HTML,无结果时替换 {{EMPTY_TIP}}:
cpp
// 拼接单个商品的HTML结构
snprintf(product, sizeof(product),
"<a href=\"detail_%s\"<div class=\"product-link\">"
"<div class=\"product\">"
"<img src=\"./%s\" "
"alt=\"%s的图片\" class=\"product-img\">"
"<div class=\"product-name\">%s</div>"
"</div></a><br>",
result->products[i].goods_id, result->products[i].goods_img, result->products[i].goods_name,
result->products[i].goods_name);
strcat(goods_html, product);
- 详情页:读取 04detail.html 模板,替换 {{GOODS_DETAIL}} 为商品完整信息(含市场价、零售价、描述)。
cpp
snprintf(detail_html, sizeof(detail_html),
"<div>"
"<img src=\"./%s\" alt=\"%s\">"
"<h3 class=\"product-name\">%s</h3>"
"<p>市场价:<span style=\"color: #999;\">%s</span></p>"
"<p>零售价:<span style=\"color: #f00;\">%s</span></p>"
"<p><br>商品描述:%s</p>"
"</div>",
product->goods_img, product->goods_name, product->goods_name, product->market_price, product->shop_price,
product->goods_desc);
4.3 资源加载与 URL 编解码
4.3.1 静态资源加载
系统需加载HTML页面、PNG/JPG图片等静态资源,通过 send_head 和 send_file 函数实现
- send_head:构造 HTTP 响应头,设置状态码、Content-Type、内容长度等:
cpp
char buf[256] = {0};
char *http_cmd[7] = {NULL};
http_cmd[0] = "HTTP/1.1 200 OK\r\n";
char date[64];
time_t now = time(NULL);
struct tm *gmt = gmtime(&now);
// 格式化GMT时间
strftime(date, sizeof(date), "Date: %a, %d %b %Y %H:%M:%S GMT\r\n", gmt);
http_cmd[1] = date;
// 根据文件类型设置Content-Type
switch (type)
{
case FILE_HTML:
http_cmd[2] = "Content-Type: text/html;charset=utf-8\r\n"; // HTML文件
break;
case FILE_PNG:
http_cmd[2] = "Content-Type: image/png\r\n"; // PNG图片
break;
case FILE_JPG:
http_cmd[2] = "Content-Type: image/jpeg\r\n"; // JPG图片
break;
default:
http_cmd[2] = "Content-Type: text/html;charset=utf-8\r\n";
}
http_cmd[3] = buf;
sprintf(buf, "content-length: %ld\r\n", file_size(file)); // 内容长度
http_cmd[4] = "Connection: keep-closed\r\n"; // 连接关闭方式
http_cmd[5] = "Server: MYWEBSer\r\n"; // 服务器标识 http_cmd[6] = http_cmd[6] = "Content-Language: zh-CN\r\n\r\n"; // 内容语言
- send_file:发送响应头后,分块读取文件内容并发送至客户端,支持大文件高效传输。
cpp
send_head(conn, filename, type);
int fd = open(filename, O_RDONLY);
while (1)
{
char buf[4096] = {0};
int rd_ret = read(fd, buf, sizeof(buf));
if (rd_ret <= 0)
{
break;
}
send(conn, buf, rd_ret, 0);
}
4.3.2 URL 编解码
解决中文等特殊字符在 HTTP 传输中的乱码问题
- 编码(urlencode):将非字母数字的字符转换为%XX格式(XX 为 ASCII 码十六进制);
- 解码(urldecode):将%XX格式还原为原始字符:
cpp
// 解码核心逻辑
if (c != '%')
{
res[res_len++] = c;
}
else
{
char c1 = url[++i];
char c0 = url[++i];
int num = hex2dec(c1) * 16 + hex2dec(c0);
res[res_len++] = num;
}
4.4 异常处理
系统包含完善的异常处理机制,覆盖常见错误场景:
- 数据库连接失败:跳转至原页面重新操作;
- 密码不一致 / 用户名重复:返回对应错误提示页;
- 无效 URL / 不支持的文件类型:返回 "当前不支持该文件类型,请尝试其他文件";
- 内存泄漏防护:通过 free_search_result 函数释放搜索结果的内存,遍历释放每个商品字段。
4.5 结果展示
结果展示包含 "用户名已存在"、"两次输入密码不一致"、"用户名或密码错误" 等异常处理情况。
电子商城信息查询系统结果展示
五、项目亮点与技术难点
5.1 项目亮点
- 轻量高效:基于 C 语言实现 HTTP 服务器,无冗余依赖,资源占用低,响应速度快;
- 模块化设计:各模块解耦,便于维护与扩展,如后续可独立新增购物车模块;
- 灵活的查询模式:支持模糊查询与精确查询,分别负责展示商品列表与单商品完整详情;
- 完整的异常处理:从参数解析到数据库操作,每个环节都有错误处理,提升系统稳定性。
5.2 技术难点
- HTTP 协议解析:手动解析HTTP请求头,提取URL与参数,需严格遵循HTTP/1.1协议格式;
- 动态页面生成:通过字符串拼接替换占位符,需处理模板格式与数据兼容性;
- 特殊字符传输:通过 URL 编解码模块,解决中文等字符的传输乱码问题;
- 内存管理:C 语言需手动管理内存,通过统一的内存释放函数,避免内存泄漏。
六、总结与未来展望
6.1 项目总结
本项目基于 C 语言、HTTP 协议与 SQLite 数据库,成功实现了电子商城信息查询系统的核心功能,包括用户注册登录、商品搜索、详情查看、静态资源加载等。系统架构清晰、代码简洁高效,解决了传统电子商城查询效率低、交互繁琐的问题,为用户提供了统一、便捷的商品信息查询入口。
6.2 未来优化方向
- 功能扩展:新增购物车、订单管理、用户个人中心等功能;
- 前端优化:使用 CSS 框架美化页面,添加 JavaScript 实现前端表单验证、异步加载;
- 性能优化:为 SQLite 数据库添加索引,提升查询速度;支持 HTTP 长连接,减少连接开销;
- 安全升级:设置密码要求(如包含大小写,长度不少于6位)、添加密码加密存储(如 MD5 哈希)、防止 SQL 注入攻击、支持 HTTPS 协议;
- 兼容性扩展:支持更多文件类型,适配移动端浏览器。
附录:完整代码
- 完整代码:详情页面顶部
- 编译运行:
- make 生成 search 可执行文件
- 执行 sudo ./search
- 在浏览器输入 http://127.0.0.1 即可打开登录页面