news 2026/6/9 16:22:07

项目(购物商城)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
项目(购物商城)

main函数

#include "fun.h" #include <fcntl.h> #include <netinet/in.h> #include <netinet/ip.h> #include <sqlite3.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <sys/socket.h> #include <sys/types.h> /* See NOTES */ #include <time.h> #include <unistd.h> int main(int argc, char **argv) { int listfd = socket(AF_INET, SOCK_STREAM, 0); if (-1 == listfd) { perror("socket"); return 1; } struct sockaddr_in ser, cil; bzero(&ser, sizeof(ser)); bzero(&cil, sizeof(cil)); ser.sin_family = AF_INET; ser.sin_port = htons(80); ser.sin_addr.s_addr = INADDR_ANY; int ret = bind(listfd, (SA)&ser, sizeof(ser)); if (-1 == ret) { perror("bind"); return 1; } listen(listfd, 3); while (1) { socklen_t len = sizeof(cil); int conn = accept(listfd, (SA)&cil, &len); if (-1 == conn) { perror("accept"); continue; } char buf[1024] = {0}; int ret = recv(conn, buf, sizeof(buf), 0); if (ret <= 0) { close(conn); continue; } printf("%s\n", buf); fflush(stdout); char *url = strtok(buf, " "); url = strtok(NULL, " "); char *val = strtok(NULL, "\r"); if (0 == strcmp(url, "/")) { send_file(conn, "./log_in.html", FILE_HTML); } else if (0 == strncmp(url, "/login", 6)) { char *name = strstr(url, "username="); name += 9; char *pass = strchr(name, '='); pass += 1; char *end = strchr(name, '&'); *end = '\0'; int is_signup = (strstr(url, "action=signup") != NULL); sqlite3 *db = NULL; int ret = sqlite3_open("1.db", &db); if (ret != SQLITE_OK) { fprintf(stderr, "sqlite3_open %s\n", sqlite3_errmsg(db)); sqlite3_close(db); break; } char *errmsg = NULL; int flag = sql_login(db, errmsg, name, pass); // 在 main 函数中,当用户登录成功后: if (flag) { // 打开商品数据库 sqlite3 *db2 = NULL; int ret2 = sqlite3_open("16web/123.db", &db2); if (ret2 != SQLITE_OK) { fprintf(stderr, "open 123.db error: %s\n", sqlite3_errmsg(db2)); sqlite3_close(db2); close(conn); continue; } send_homepage(db2, conn); } else { if (is_signup) { int errmsg_signup = sql_signup(db, errmsg, name, pass); if (errmsg_signup) { int flag = sql_login(db, errmsg, name, pass); if (flag) { sqlite3 *db2 = NULL; int ret2 = sqlite3_open("16web/123.db", &db2); if (ret2 != SQLITE_OK) { fprintf(stderr, "open 123.db error: %s\n", sqlite3_errmsg(db2)); sqlite3_close(db2); close(conn); continue; } send_homepage(db2, conn); } } else { send_file(conn, "./log_error.html", FILE_HTML); } } else { send_file(conn, "./log_error.html", FILE_HTML); } } sqlite3_close(db); } else if (0 == strncmp(url, "/search", 7)) { char *want_find = strstr(url, "want="); if (!want_find) { const char *badreq = "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n"; send(conn, badreq, strlen(badreq), 0); close(conn); continue; } want_find += 5; urldecode(want_find); sqlite3 *db = NULL; int ret = sqlite3_open("16web/123.db", &db); if (ret != SQLITE_OK) { fprintf(stderr, "DB open error: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); close(conn); continue; } // 使用参数化查询防止 SQL 注入(推荐) const char *sql = "SELECT goods_name, keywords, goods_desc, goods_thumb, goods_img FROM goods WHERE goods_name " "LIKE ? LIMIT 1;"; sqlite3_stmt *stmt; if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) { fprintf(stderr, "Prepare error: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); close(conn); continue; } char like_pattern[512]; snprintf(like_pattern, sizeof(like_pattern), "%%%s%%", want_find); sqlite3_bind_text(stmt, 1, like_pattern, -1, SQLITE_STATIC); char response[8192] = {0}; int total = 0; if (sqlite3_step(stmt) == SQLITE_ROW) { const char *name = (const char *)sqlite3_column_text(stmt, 0); const char *keywords = (const char *)sqlite3_column_text(stmt, 1); const char *desc = (const char *)sqlite3_column_text(stmt, 2); const char *thumb = (const char *)sqlite3_column_text(stmt, 3); const char *image = (const char *)sqlite3_column_text(stmt, 4); total = snprintf(response, sizeof(response), "HTTP/1.1 200 OK\r\n" "Content-Type: text/html; charset=utf-8\r\n" "Connection: close\r\n" "\r\n" "<!DOCTYPE html>\n" "<html><head><meta charset=\"utf-8\"><title>%s</title></head>\n" "<style>\n" "body{background-image: url(background.jpg);" "background-repeat: no-repeat;" "background-size: cover;" "background-position: center;" "text-align: center;" "margin: 0;" "padding: 20px;" "min-height: 100vh;" "box-sizing: border-box;}" " </style>\n" "<body>\n" "<h1>%s</h1>\n" "<p><b>关键词:</b> %s</p>\n" "<p><b>描述:</b> %s</p>\n", name, name, keywords ? keywords : "", desc ? desc : ""); if (image && strlen(image) > 0) { char goods_img[4096]; snprintf(goods_img, sizeof(goods_img), "/16web/%s", image); total += snprintf(response + total, sizeof(response) - total, "<p><img src=\"%s\" alt=\"%s\" style=\"max-width:300px;\"></p>\n", goods_img, name); } total += snprintf(response + total, sizeof(response) - total, "</body></html>"); send(conn, response, total, 0); } else { const char *notfound = "HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\n<h1>未找到商品</h1>"; send(conn, notfound, strlen(notfound), 0); } sqlite3_finalize(stmt); sqlite3_close(db); } else if (0 == strncmp(url, "/sousuo", 7)) { char *want_find = strstr(url, "want="); if (!want_find) { const char *badreq = "HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n"; send(conn, badreq, strlen(badreq), 0); close(conn); continue; } want_find += 5; // 跳过 "want=" urldecode(want_find); // 解码 URL 编码(如 %E6%89%8B%E6%9C%BA → 手机) // 打开数据库 sqlite3 *db = NULL; if (sqlite3_open("16web/123.db", &db) != SQLITE_OK) { fprintf(stderr, "DB open error: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); close(conn); continue; } // ✅ 安全的参数化查询:使用 ? 占位符 const char *sql = "SELECT goods_name, goods_thumb FROM goods WHERE goods_name LIKE ?"; sqlite3_stmt *stmt; if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) { fprintf(stderr, "SQL prepare failed: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); close(conn); continue; } // 构造 LIKE 模式:%用户输入% char like_pattern[512]; snprintf(like_pattern, sizeof(like_pattern), "%%%s%%", want_find); // 绑定参数(自动处理特殊字符,防注入) sqlite3_bind_text(stmt, 1, like_pattern, -1, SQLITE_STATIC); // 构建 HTML 响应 char response[65536] = {0}; int total = snprintf(response, sizeof(response), "HTTP/1.1 200 OK\r\n" "Content-Type: text/html; charset=utf-8\r\n" "Connection: close\r\n" "\r\n" "<!DOCTYPE html>\n" "<html>\n" "<head>\n" " <meta charset=\"utf-8\">\n" " <title>搜索结果</title>\n" " <style>\n" " .product { display: inline-block; margin: 10px; text-align: center; width: 180px; }\n" " .product img { max-width: 160px; height: auto; border: 1px solid #ddd; }\n" " .product p { font-size: 14px; margin: 5px 0; }\n" "body{background-image: url(background.jpg);" "background-repeat: no-repeat;" "background-size: cover;" "background-position: center;" "text-align: center;" "margin: 0;" "padding: 20px;" "min-height: 100vh;" "box-sizing: border-box;}" " </style>\n" "</head>\n" "<body>\n"); int found = 0; // 遍历所有匹配的商品 while (sqlite3_step(stmt) == SQLITE_ROW && total < (int)sizeof(response) - 1000) { found = 1; const char *name = (const char *)sqlite3_column_text(stmt, 0); const char *thumb = (const char *)sqlite3_column_text(stmt, 1); // 第1列! // 对商品名进行 URL 编码,用于生成安全链接 char encoded_name[2048]; strncpy(encoded_name, name, sizeof(encoded_name) - 1); encoded_name[sizeof(encoded_name) - 1] = '\0'; urlencode(encoded_name); total += snprintf(response + total, sizeof(response) - total, "<div class=\"product\">\n" " <a href=\"/search?want=%s\"><img src=\"/16web/%s\" alt=\"%s\"></a>\n" " <p><a href=\"/search?want=%s\">%s</a></p>\n" "</div>\n", encoded_name, thumb ? thumb : "", name, encoded_name, name); } if (!found) { total += snprintf(response + total, sizeof(response) - total, "<p>未找到包含“%s”的商品。</p>", want_find); } total += snprintf(response + total, sizeof(response) - total, "</body></html>"); send(conn, response, total, 0); // 清理资源 sqlite3_finalize(stmt); sqlite3_close(db); } else if (strlen(url) > 4 && 0 == strcmp(&url[strlen(url) - 4], ".jpg")) { send_file(conn, url + 1, FILE_JPG); } else if (strlen(url) > 4 && 0 == strcmp(&url[strlen(url) - 4], ".ico")) { send_file(conn, "label.ico", FILE_PNG); } else if (strlen(url) > 4 && 0 == strcmp(&url[strlen(url) - 4], ".png")) { send_file(conn, url + 1, FILE_PNG); } else if (strlen(url) > 4 && 0 == strcmp(&url[strlen(url) - 4], ".bmp")) { send_file(conn, url + 1, FILE_BMP); } else if (strlen(url) > 5 && 0 == strcmp(&url[strlen(url) - 5], ".html")) { send_file(conn, url + 1, FILE_HTML); } close(conn); } close(listfd); return 0; }

fun.c

#include "fun.h" #include <fcntl.h> #include <netinet/in.h> #include <netinet/ip.h> #include <sqlite3.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> /* See NOTES */ #include <time.h> #include <unistd.h> long file_size(char *file) { int fd = open(file, O_RDONLY); if (-1 == fd) { perror("file size open error"); fprintf(stderr, "filename is %s\n", file); return 0; } long size = lseek(fd, 0, SEEK_END); return size; } int send_head(int conn, char *file, FILE_TYPE type) { char buf[256] = {0}; char *http_cmd[7] = {NULL}; http_cmd[0] = "HTTP/1.1 200 OK\r\n"; http_cmd[1] = "Date: Wed, 31 Dec 2025 01:58:31 GMT\r\n"; switch (type) { case FILE_HTML: http_cmd[2] = "Content-Type: text/html;charset=utf-8\r\n"; break; case FILE_PNG: http_cmd[2] = "Content-Type: image/png\r\n"; break; case FILE_JPG: http_cmd[2] = "Content-Type: image/jpeg\r\n"; break; case FILE_BMP: http_cmd[2] = "Content-Type: image/bmp\r\n"; 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] = "Content-Language: zh-CN\r\n\r\n"; int i = 0; for (i = 0; i < 7; i++) { send(conn, http_cmd[i], strlen(http_cmd[i]), 0); } return 0; } int send_file(int conn, char *filename, FILE_TYPE type) { send_head(conn, filename, type); int fd = open(filename, O_RDONLY); if (-1 == fd) { perror("open"); return 1; } 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); } close(fd); return 0; } int select_login(void *arg, int col, char **result, char **title) { *(int *)arg = 1; return 0; } int sql_login(sqlite3 *db, char *errmsg, char *name, char *pass) { int flag = 0; char sql_cmd[1024] = {0}; sprintf(sql_cmd, "select * from html where id = '%s' and pass = '%s';", name, pass); int ret = sqlite3_exec(db, sql_cmd, select_login, &flag, &errmsg); if (ret != SQLITE_OK) { fprintf(stderr, "sqlite3_exec %s\n", errmsg); sqlite3_free(errmsg); } return flag; } int sql_signup(sqlite3 *db, char *errmsg, char *name, char *pass) { char sql_cmd[1024] = {0}; sprintf(sql_cmd, "insert into html values('%s','%s');", name, pass); int ret = sqlite3_exec(db, sql_cmd, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { fprintf(stderr, "sqlite3_exec %s\n", errmsg); return 0; sqlite3_free(errmsg); } return 1; } #define BURSIZE 2048 int hex2dec(char c) { if ('0' <= c && c <= '9') { return c - '0'; } else if ('a' <= c && c <= 'f') { return c - 'a' + 10; } else if ('A' <= c && c <= 'F') { return c - 'A' + 10; } else { return -1; } } char dec2hex(short int c) { if (0 <= c && c <= 9) { return c + '0'; } else if (10 <= c && c <= 15) { return c + 'A' - 10; } else { return -1; } } //编码一个url void urlencode(char url[]) { int i = 0; int len = strlen(url); int res_len = 0; char res[BURSIZE]; for (i = 0; i < len; ++i) { char c = url[i]; if (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '/' || c == '.') { res[res_len++] = c; } else { int j = (short int)c; if (j < 0) j += 256; int i1, i0; i1 = j / 16; i0 = j - i1 * 16; res[res_len++] = '%'; res[res_len++] = dec2hex(i1); res[res_len++] = dec2hex(i0); } } res[res_len] = '\0'; strcpy(url, res); } // 解码url void urldecode(char url[]) { int i = 0; int len = strlen(url); int res_len = 0; char res[BURSIZE]; for (i = 0; i < len; ++i) { char c = url[i]; if (c != '%') { res[res_len++] = c; } else { char c1 = url[++i]; char c0 = url[++i]; int num = 0; num = hex2dec(c1) * 16 + hex2dec(c0); res[res_len++] = num; } } res[res_len] = '\0'; strcpy(url, res); } // fun.c int callback(void *data, int argc, char **argv, char **azColName) { struct SearchResult *result = (struct SearchResult *)data; if (result->count >= 50) { return 0; // 超过上限,不再保存 } struct GoodsItem *item = &result->items[result->count]; // 安全复制字段(对照 SELECT 顺序!) strncpy(item->goods_name, argv[0] ? argv[0] : "", 512 - 1); strncpy(item->keywords, argv[1] ? argv[1] : "", 1024 - 1); strncpy(item->goods_thumb, argv[2] ? argv[2] : "", 1024 - 1); strncpy(item->goods_img, argv[3] ? argv[3] : "", 1024 - 1); strncpy(item->original_img, argv[4] ? argv[4] : "", 1024 - 1); // 确保字符串以 \0 结尾 item->goods_name[512 - 1] = '\0'; item->keywords[1024 - 1] = '\0'; item->goods_thumb[1024 - 1] = '\0'; item->goods_img[1024 - 1] = '\0'; item->original_img[1024 - 1] = '\0'; result->count++; return 0; } int send_homepage(sqlite3 *db2, int conn) { const char *sql = "SELECT goods_name, goods_thumb FROM goods;"; sqlite3_stmt *stmt; if (sqlite3_prepare_v2(db2, sql, -1, &stmt, NULL) != SQLITE_OK) { fprintf(stderr, "SQL prepare error: %s\n", sqlite3_errmsg(db2)); sqlite3_close(db2); close(conn); } // 构建响应 char response[65536] = {0}; int total = snprintf(response, sizeof(response), "HTTP/1.1 200 OK\r\n" "Content-Type: text/html; charset=utf-8\r\n" "Connection: close\r\n" "\r\n" "<!DOCTYPE html>\n" "<html>\n" "<head>\n" " <meta charset=\"utf-8\">\n" " <style>\n" " .product { display: inline-block; margin: 10px; text-align: center; width: 180px; }\n" " .product img { max-width: 160px; height: auto; border: 1px solid #ddd; }\n" " .product p { font-size: 14px; margin: 5px 0; }\n" "body{ background-image: url(background.jpg);" "background-repeat: no-repeat;" "background-size: cover;" "background-position: center;" "text-align: center;" "margin: 0;" "padding: 20px;" "min-height: 100vh;" "box-sizing: border-box;}" " </style>\n" "</head>\n" "<body>\n" "<form action=\"/sousuo\" method=\"GET\" class=\"search-box\">\n" "<input type=\"text\" name=\"want\" placeholder=\"搜索\" required>\n" "<input type=\"submit\" value=\"搜索\">\n" "</form>\n"); while (sqlite3_step(stmt) == SQLITE_ROW) //&& total < (int)sizeof(response) - 1000) { const char *name = (const char *)sqlite3_column_text(stmt, 0); const char *thumb = (const char *)sqlite3_column_text(stmt, 1); // 使用 urlencode 对商品名进行编码,以便安全地作为 URL 参数传递 char encoded_name[2048]; strcpy(encoded_name, name); urlencode(encoded_name); total += sprintf(response + total, "<div class=\"product\">\n" " <a href=\"/search?want=%s\"><img src=\"/16web/%s\" alt=\"%s\"></a>\n" " <p><a href=\"/search?want=%s\">%s</a></p>\n" "</div>\n", encoded_name, thumb, name, encoded_name, name); } total += sprintf(response + total, "</body>\n" "</html>\n"); send(conn, response, total, 0); sqlite3_finalize(stmt); sqlite3_close(db2); return 0; }

fun.h

#ifndef __FUN_H_ #define __FUN_H_ #include <sqlite3.h> typedef struct sockaddr *(SA); typedef enum { FILE_HTML, FILE_PNG, FILE_JPG, FILE_BMP } FILE_TYPE; long file_size(char* file); int send_head(int conn, char* file, FILE_TYPE type); int send_file(int conn, char* filename, FILE_TYPE type); int select_login(void *arg, int col, char **result, char **title); int sql_login(sqlite3 *db,char *errmsg,char *name ,char *pass); int sql_signup(sqlite3 *db,char *errmsg,char *name ,char *pass); int hex2dec(char c); char dec2hex(short int c); void urlencode(char url[]); void urldecode(char url[]); int callback(void *data, int argc, char **argv, char **azColName); // fun.h struct GoodsItem { char goods_name[512]; char keywords[1024]; char goods_thumb[1024]; char goods_img[1024]; char original_img[1024]; char goods_desc[1024]; }; struct SearchResult { int count; // 实际找到多少个 struct GoodsItem items[50]; // 商品列表 }; int send_homepage(sqlite3 *db2, int conn); #endif

上述为程序源码。

下面就是实现效果,

1.登录界面

2.未注册则跳转注册界面

3.注册完成后登录则进入商城界面

4.点击搜索框可搜索商品(例:搜索三星)

(点击图形也可跳转详情界面。。。。)

5.跳转搜索三星后界面

(点击图片则进入详情页)

6.进入详情页

程序到这执行基本完毕。(也可退回点击其他商品进行查看商品详情)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/29 22:20:35

五款热门翻译模型横向评测:响应速度与资源占用排名

五款热门翻译模型横向评测&#xff1a;响应速度与资源占用排名 &#x1f4ca; 评测背景与目标 随着全球化进程加速&#xff0c;高质量的中英翻译需求日益增长。在 AI 驱动的自然语言处理领域&#xff0c;神经网络机器翻译&#xff08;NMT&#xff09;已成为主流技术方案。然而&…

作者头像 李华
网站建设 2026/6/2 20:05:28

MusicFree插件终极指南:打造你的专属音乐宇宙

MusicFree插件终极指南&#xff1a;打造你的专属音乐宇宙 【免费下载链接】MusicFreePlugins MusicFree播放插件 项目地址: https://gitcode.com/gh_mirrors/mu/MusicFreePlugins 在数字音乐时代&#xff0c;MusicFree插件系统为用户提供了一个全新的音乐体验方式。通过…

作者头像 李华
网站建设 2026/6/7 4:38:45

IDEA摸鱼阅读神器Thief-Book终极指南:代码间隙的隐秘阅读空间

IDEA摸鱼阅读神器Thief-Book终极指南&#xff1a;代码间隙的隐秘阅读空间 【免费下载链接】thief-book-idea IDEA插件版上班摸鱼看书神器 项目地址: https://gitcode.com/gh_mirrors/th/thief-book-idea 在紧张的编程工作中&#xff0c;每个开发者都需要短暂的休息来调整…

作者头像 李华
网站建设 2026/5/31 21:44:45

联想拯救者工具箱性能优化指南:解决笔记本卡顿与续航问题

联想拯救者工具箱性能优化指南&#xff1a;解决笔记本卡顿与续航问题 【免费下载链接】LenovoLegionToolkit Lightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops. 项目地址: https://gitcode.com/gh_mirrors/le/LenovoLegionToolkit 还在为…

作者头像 李华
网站建设 2026/6/3 1:06:44

百度网盘直链下载终极指南:三步实现满速下载体验

百度网盘直链下载终极指南&#xff1a;三步实现满速下载体验 【免费下载链接】baiduyun 油猴脚本 - 一个免费开源的网盘下载助手 项目地址: https://gitcode.com/gh_mirrors/ba/baiduyun 还在为百度网盘龟速下载而苦恼吗&#xff1f;网盘直链下载助手为你提供完美的解决…

作者头像 李华
网站建设 2026/5/30 18:40:46

DOL汉化美化整合包:终极完整安装与使用指南

DOL汉化美化整合包&#xff1a;终极完整安装与使用指南 【免费下载链接】DOL-CHS-MODS Degrees of Lewdity 整合 项目地址: https://gitcode.com/gh_mirrors/do/DOL-CHS-MODS 想要快速体验DOL汉化美化整合包的强大功能吗&#xff1f;这个一站式解决方案为您带来了高质量…

作者头像 李华