专业的网站制作莱州人才网
2026/3/17 21:07:30 网站建设 项目流程
专业的网站制作,莱州人才网,整站下载器 安卓版,被电商代运营骗了怎么办Web服务器项目代码解析 项目概述 这是一个基于C语言实现的轻量级Web服务器#xff0c;具备用户登录、商品搜索、商品详情展示等功能#xff0c;使用SQLite数据库存储数据#xff0c;支持HTTP协议处理。 一、文件结构说明 1. HTML模板文件#xff08;前端页面#xff0…Web服务器项目代码解析项目概述这是一个基于C语言实现的轻量级Web服务器具备用户登录、商品搜索、商品详情展示等功能使用SQLite数据库存储数据支持HTTP协议处理。一、文件结构说明1. HTML模板文件前端页面项目包含6个HTML模板文件位于html/目录下1.1detail.html- 商品详情页!DOCTYPE html html head meta charsetutf-8 title商品详情/title /head body !-- 页面结构商品图片、名称、价格、简介、详细描述 -- div classproduct-detail img idproduct-img src alt商品图片 h1 idproduct-name商品名称/h1 div idproduct-price¥0.00/div !-- ... 其他内容 ... -- /div /body /html1.2error.html- 错误页面!DOCTYPE html html head meta charsetutf-8 title登陆/title /head body div classerror-container h1出错了/h1 p抱歉页面出现了一些问题请稍后再试。/p div classlinks a href/login.html返回登录/a a href/search.html返回搜索/a /div /div /body /html用于显示系统错误或登录失败提供返回登录页和搜索页的链接1.3list.html- 商品列表页!DOCTYPE html html head meta charsetutf-8 title商品/title /head body div classheader h1商品搜索结果/h1 a href/search.html classback-link返回搜索/a /div div classsearch-box form action/search methodGET input typetext namekeyword placeholder继续搜索... value{{KEYWORD}} button typesubmit搜索/button /form /div div classresult-count 找到 span idproduct-count0/span 个商品 /div div classproduct-grid !-- 这里将被商品列表替换 -- /div /body /html显示搜索结果包含继续搜索的表单使用模板变量{{KEYWORD}}动态填充搜索关键词1.4login.html- 用户登录页!DOCTYPE html html head meta charsetutf-8 title登录/title /head body h2用户登录/h2 form actionlogin 用户名: input typetext nameusername requiredrequired placeholder请输入账号br 密码: input typepassword namepassword requiredrequired placeholder请输入密码br button typesubmit登录/button a href/register.html注册/a /form /body /html1.5register.html- 用户注册页!DOCTYPE html html head meta charsetutf-8 title注册/title /head body h2用户注册/h2 form action/register methodGET div classinput-group input typetext nameusername placeholder用户名 required /div div classinput-group input typepassword namepassword placeholder密码 required /div button typesubmit注册/button /form div classlinks a href/login.html已有账号立即登录/a /div /div /body /html简单的注册表单提供跳转到登录页的链接1.6search.html- 搜索主页!DOCTYPE html html head meta charsetutf-8 title搜索/title /head body h1搜索商品/h1 form action/search methodGET input typetext namekeyword placeholder输入商品名称 required button typesubmit搜索/button /form div classkeyword h3热门搜索:/h3 a href/search?keyword诺基亚诺基亚/a a href/search?keyword手机手机/a a href/search?keyword耳机耳机/a a href/search?keyword充电器充电器/a a href/search?keyword三星三星/a a href/search?keyword摩托罗拉摩托罗拉/a a href/search?keyword索爱索爱/a /div /body /html搜索表单热门搜索关键词链接诺基亚、手机、耳机等2. C语言源代码文件2.1ser.c- 主服务器程序2.1.1 数据库初始化void init_database() { if (sqlite3_open(123.db, db) ! SQLITE_OK) { printf(数据库连接失败: %s\n, sqlite3_errmsg(db)); exit(1); } sqlite3_exec(db, PRAGMA encoding UTF-8, NULL, NULL, NULL); }连接SQLite数据库123.db设置数据库编码为UTF-8支持中文2.1.2 HTTP响应处理函数void send_http_response(int conn, const char *content_type, const char *content) { char header[512]; long len strlen(content); sprintf(header, HTTP/1.1 200 OK\r\n Content-Type: %s; charsetutf-8\r\n Content-Length: %ld\r\n Connection: close\r\n\r\n, content_type, len); send(conn, header, strlen(header), 0); send(conn, content, len, 0); }2.1.3 文件发送函数void send_file(int conn, const char *filename) { FILE *fp fopen(filename, rb); if (!fp) { char *error HTTP/1.1 404 Not Found\r\n\r\nh1404 Not Found/h1; send(conn, error, strlen(error), 0); return; } // ... 根据文件扩展名设置Content-Type ... }支持HTML、JPEG、PNG、GIF等文件类型自动设置正确的Content-Type头部2.1.4 用户登录验证int check_login(const char *user, const char *pass) { sqlite3_stmt *stmt; const char *sql SELECT user_id FROM admin_user WHERE user_name ? AND password ?; // 使用预编译语句防止SQL注入 sqlite3_bind_text(stmt, 1, user, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, pass, -1, SQLITE_STATIC); // ... 执行查询 ... }2.1.5 商品图片查找char *find_product_image(int goods_id) { static char img_path[512]; const char *dirs[] { images/200905/thumb_img, // 缩略图目录 images/200905/goods_img, // 商品图目录 images/200905/source_img, // 原图目录 images // 根图片目录 }; // 按目录优先级查找商品图片 // 格式{goods_id}_xxx.jpg // 如果找不到使用默认图片no_picture.gif }2.1.6 商品搜索处理void handle_search(int conn, const char *keyword) { // SQL查询在商品名称和简介中搜索关键词 const char *sql SELECT goods_id, goods_name, shop_price, goods_brief FROM goods WHERE goods_name LIKE ? OR goods_brief LIKE ? LIMIT 50; // 构建包含商品图片、名称、价格、详情的HTML响应 }2.1.7 商品详情处理void handle_detail(int conn, int product_id) { // 查询商品详细信息 const char *sql SELECT goods_name, shop_price, goods_desc, goods_brief FROM goods WHERE goods_id ?; // 生成包含完整商品信息的HTML页面 }2.1.8 URL参数解析void get_url_param(char *url, const char *name, char *output, int size) { // 从URL中提取参数值 // 例如从/search?keyword手机中提取keyword的值手机 // 支持URL解码处理中文字符 }2.1.9 主服务器循环int main() { // 1. 初始化数据库 // 2. 创建socket绑定8080端口 // 3. 监听连接请求 // 4. 处理HTTP请求路由分发 // 5. 关闭连接循环继续 }路由处理逻辑if (strcmp(url, /) 0 || strcmp(url, /login.html) 0) { send_file(conn, html/login.html); } else if (strncmp(url, /login?, 7) 0) { // 处理登录请求 } else if (strncmp(url, /search?, 8) 0) { // 处理搜索请求 } else if (strncmp(url, /detail/, 8) 0) { // 处理商品详情请求 } // ... 其他路由 ...2.1.10 代码#include url2.h #include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/socket.h #include netinet/in.h #include sqlite3.h #include dirent.h #include fcntl.h typedef struct sockaddr *SA; sqlite3 *db NULL; void init_database() { if (sqlite3_open(123.db, db) ! SQLITE_OK) { printf(数据库连接失败: %s\n, sqlite3_errmsg(db)); exit(1); } printf(数据库连接成功\n); sqlite3_exec(db, PRAGMA encoding UTF-8, NULL, NULL, NULL); } int file_exists(const char *path) { FILE *fp fopen(path, rb); if (fp) { fclose(fp); return 1; } return 0; } void send_http_response(int conn, const char *content_type, const char *content) { char header[512]; long len strlen(content); sprintf(header, HTTP/1.1 200 OK\r\n Content-Type: %s; charsetutf-8\r\n Content-Length: %ld\r\n Connection: close\r\n\r\n, content_type, len); send(conn, header, strlen(header), 0); send(conn, content, len, 0); } void send_file(int conn, const char *filename) { FILE *fp fopen(filename, rb); if (!fp) { char *error HTTP/1.1 404 Not Found\r\n\r\nh1404 Not Found/h1; send(conn, error, strlen(error), 0); return; } fseek(fp, 0, SEEK_END); long size ftell(fp); fseek(fp, 0, SEEK_SET); const char *content_type text/plain; if (strstr(filename, .html)) content_type text/html; else if (strstr(filename, .jpg) || strstr(filename, .jpeg)) content_type image/jpeg; else if (strstr(filename, .png)) content_type image/png; else if (strstr(filename, .gif)) content_type image/gif; char header[512]; sprintf(header, HTTP/1.1 200 OK\r\n Content-Type: %s\r\n Content-Length: %ld\r\n Connection: close\r\n\r\n, content_type, size); send(conn, header, strlen(header), 0); char buffer[4096]; size_t bytes_read; while ((bytes_read fread(buffer, 1, sizeof(buffer), fp)) 0) { send(conn, buffer, bytes_read, 0); } fclose(fp); } char *safe_get_text(sqlite3_stmt *stmt, int col) { const unsigned char *text sqlite3_column_text(stmt, col); if (!text) return strdup(); int len sqlite3_column_bytes(stmt, col); if (len 0) return strdup(); char *result malloc(len 1); memcpy(result, text, len); result[len] \0; return result; } int check_login(const char *user, const char *pass) { sqlite3_stmt *stmt; const char *sql SELECT user_id FROM admin_user WHERE user_name ? AND password ?; if (sqlite3_prepare_v2(db, sql, -1, stmt, NULL) SQLITE_OK) { sqlite3_bind_text(stmt, 1, user, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, pass, -1, SQLITE_STATIC); if (sqlite3_step(stmt) SQLITE_ROW) { sqlite3_finalize(stmt); return 1; } sqlite3_finalize(stmt); } return 0; } char *find_product_image(int goods_id) { static char img_path[512]; const char *dirs[] { images/200905/thumb_img, images/200905/goods_img, images/200905/source_img, images }; for (int d 0; d 4; d) { DIR *dir opendir(dirs[d]); if (dir) { struct dirent *entry; char prefix[50]; snprintf(prefix, sizeof(prefix), %d_, goods_id); while ((entry readdir(dir)) ! NULL) { if (strncmp(entry-d_name, prefix, strlen(prefix)) 0) { snprintf(img_path, sizeof(img_path), %s/%s, dirs[d], entry-d_name); closedir(dir); if (file_exists(img_path)) return img_path; } } closedir(dir); } } if (file_exists(images/no_picture.gif)) strcpy(img_path, images/no_picture.gif); else strcpy(img_path, ); return img_path; } void handle_search(int conn, const char *keyword) { sqlite3_stmt *stmt; const char *sql SELECT goods_id, goods_name, shop_price, goods_brief FROM goods WHERE goods_name LIKE ? OR goods_brief LIKE ? LIMIT 50; if (sqlite3_prepare_v2(db, sql, -1, stmt, NULL) ! SQLITE_OK) { send_http_response(conn, text/html, h1数据库查询错误/h1); return; } char like[256]; snprintf(like, sizeof(like), %%%s%%, keyword); sqlite3_bind_text(stmt, 1, like, -1, SQLITE_STATIC); sqlite3_bind_text(stmt, 2, like, -1, SQLITE_STATIC); char html[65536]; snprintf(html, sizeof(html), !DOCTYPE html htmlheadmeta charsetutf-8title搜索结果/title style body { font-family: Arial; margin: 20px; } .header { background: #f0f0f0; padding: 10px; margin-bottom: 20px; } .product-grid { display: flex; flex-wrap: wrap; } .product-item { border: 1px solid #ddd; margin: 10px; padding: 15px; width: 280px; } .product-item img { max-width: 120px; max-height: 120px; } .price { color: #e44; font-size: 18px; font-weight: bold; } .detail-link { display: inline-block; margin-top: 10px; padding: 5px 10px; background: #007bff; color: white; text-decoration: none; } /style/headbody div classheaderh1商品搜索结果/h1p搜索关键词: strong%s/strong/p a href/search.html返回搜索/a/div form action/search methodGET stylemargin: 20px 0; input typetext namekeyword value%s stylepadding: 5px; width: 300px; button typesubmit stylepadding: 5px 15px;搜索/button/form div classproduct-grid, keyword, keyword); int count 0; while (sqlite3_step(stmt) SQLITE_ROW) { int id sqlite3_column_int(stmt, 0); char *name safe_get_text(stmt, 1); double price sqlite3_column_double(stmt, 2); char *brief safe_get_text(stmt, 3); char *img_path find_product_image(id); char item[1024]; if (strlen(img_path) 0) { snprintf(item, sizeof(item), div classproduct-itemimg src/%s alt%s h3a href/detail/%d%s/a/h3 p classprice¥%.2f/pp%s/p a classdetail-link href/detail/%d查看详情/a/div, img_path, name, id, name, price, brief, id); } else { snprintf(item, sizeof(item), div classproduct-itemh3a href/detail/%d%s/a/h3 p classprice¥%.2f/pp%s/p a classdetail-link href/detail/%d查看详情/a/div, id, name, price, brief, id); } strcat(html, item); count; free(name); free(brief); } sqlite3_finalize(stmt); strcat(html, /div); if (count 0) strcat(html, p未找到相关商品/p); else { char count_msg[50]; snprintf(count_msg, sizeof(count_msg), p共找到 strong%d/strong 个商品/p, count); strcat(html, count_msg); } strcat(html, bra href/search.html返回搜索页面/a/body/html); send_http_response(conn, text/html, html); } void handle_detail(int conn, int product_id) { sqlite3_stmt *stmt; const char *sql SELECT goods_name, shop_price, goods_desc, goods_brief FROM goods WHERE goods_id ?; if (sqlite3_prepare_v2(db, sql, -1, stmt, NULL) ! SQLITE_OK) { send_http_response(conn, text/html, h1数据库查询错误/h1); return; } sqlite3_bind_int(stmt, 1, product_id); if (sqlite3_step(stmt) ! SQLITE_ROW) { char error[256]; snprintf(error, sizeof(error), h1商品不存在 (ID: %d)/h1, product_id); send_http_response(conn, text/html, error); sqlite3_finalize(stmt); return; } char *name safe_get_text(stmt, 0); double price sqlite3_column_double(stmt, 1); char *desc safe_get_text(stmt, 2); char *brief safe_get_text(stmt, 3); sqlite3_finalize(stmt); char *img_path find_product_image(product_id); char html[32768]; snprintf(html, sizeof(html), !DOCTYPE htmlhtmlheadmeta charsetutf-8title%s/title style body { font-family: Arial; margin: 20px; } .header { background: #f0f0f0; padding: 15px; margin-bottom: 20px; } .product-detail { max-width: 800px; } .product-image { float: left; margin-right: 30px; } .product-image img { max-width: 300px; max-height: 300px; border: 1px solid #ddd; } .product-info { overflow: hidden; } .product-name { font-size: 28px; margin: 0 0 10px 0; } .price { color: #e44; font-size: 32px; font-weight: bold; margin: 10px 0; } .brief { color: #666; font-size: 16px; margin: 15px 0; } .desc-title { font-size: 20px; margin: 25px 0 10px 0; border-bottom: 2px solid #007bff; } .description { line-height: 1.6; margin: 15px 0; } .action-buttons { margin-top: 30px; clear: both; } .action-btn { display: inline-block; padding: 10px 25px; margin-right: 15px; background: #007bff; color: white; text-decoration: none; border-radius: 4px; } .back-btn { background: #6c757d; } .continue-btn { background: #28a745; } /style/headbody div classheaderh1商品详情/h1a href/search.html返回搜索/a/div div classproduct-detail, name); if (strlen(img_path) 0) { char img_section[512]; snprintf(img_section, sizeof(img_section), div classproduct-imageimg src/%s alt%s/div, img_path, name); strcat(html, img_section); } char info_section[20480]; snprintf(info_section, sizeof(info_section), div classproduct-info h1 classproduct-name%s/h1 div classprice¥%.2f/div div classbriefstrong商品简介:/strong %s/div h3 classdesc-title详细描述/h3 div classdescription%s/div /div div classaction-buttons a hrefjavascript:history.back() classaction-btn back-btn返回列表/a a href/search.html classaction-btn continue-btn继续购物/a /div/div/body/html, name, price, brief, desc); strcat(html, info_section); send_http_response(conn, text/html, html); free(name); free(desc); free(brief); } void get_url_param(char *url, const char *name, char *output, int size) { char search[256]; snprintf(search, sizeof(search), %s, name); char *start strstr(url, search); if (!start) { output[0] \0; return; } start strlen(search); char *end strchr(start, ); if (!end) end strchr(start, ); if (!end) end strchr(start, \n); if (!end) end start strlen(start); int len end - start; if (len size) len size - 1; strncpy(output, start, len); output[len] \0; urldecode(output); } int main() { init_database(); int sock socket(AF_INET, SOCK_STREAM, 0); if (sock 0) { perror(创建socket失败); return 1; } int opt 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, opt, sizeof(opt)); struct sockaddr_in addr {0}; addr.sin_family AF_INET; addr.sin_port htons(8080); addr.sin_addr.s_addr INADDR_ANY; if (bind(sock, (SA)addr, sizeof(addr)) 0) { perror(绑定端口失败); close(sock); return 1; } listen(sock, 5); printf(服务器运行在: http://localhost:8080\n); while (1) { struct sockaddr_in client; socklen_t len sizeof(client); int conn accept(sock, (SA)client, len); if (conn 0) continue; char buf[8192]; int bytes recv(conn, buf, sizeof(buf) - 1, 0); if (bytes 0) { close(conn); continue; } buf[bytes] \0; char *method strtok(buf, ); char *url strtok(NULL, ); if (!method || !url) { close(conn); continue; } printf(请求: %s %s\n, method, url); if (strcmp(url, /) 0 || strcmp(url, /login.html) 0) { send_file(conn, html/login.html); } else if (strcmp(url, /search.html) 0) { send_file(conn, html/search.html); } else if (strcmp(url, /register.html) 0) { send_file(conn, html/register.html); } else if (strncmp(url, /images/, 8) 0) { send_file(conn, url 1); } else if (strncmp(url, /login?, 7) 0) { char username[256], password[256]; get_url_param(url, username, username, sizeof(username)); get_url_param(url, password, password, sizeof(password)); if (check_login(username, password)) { char *redirect HTTP/1.1 302 Found\r\nLocation: /search.html\r\n\r\n; send(conn, redirect, strlen(redirect), 0); } else { send_file(conn, html/error.html); } } else if (strncmp(url, /search?, 8) 0) { char keyword[256]; get_url_param(url, keyword, keyword, sizeof(keyword)); handle_search(conn, keyword); } else if (strncmp(url, /detail/, 8) 0) { int id atoi(url 8); handle_detail(conn, id); } else if (strstr(url, .html)) { char filepath[256]; snprintf(filepath, sizeof(filepath), html%s, url); send_file(conn, filepath); } else if (strstr(url, .ico)) { char *resp HTTP/1.1 204 No Content\r\n\r\n; send(conn, resp, strlen(resp), 0); } else { send_file(conn, html/error.html); } close(conn); } sqlite3_close(db); close(sock); return 0; }2.2url2.c- URL编码/解码工具2.2.1 URL编码函数void urlencode(char url[]) { // 将特殊字符转换为%XX格式 // 保留字母、数字、斜杠和点号 // 例如测试 - %E6%B5%8B%E8%AF%95 }2.2.2 URL解码函数void urldecode(char url[]) { // 将%XX格式转换回原始字符 // 例如%E6%B5%8B%E8%AF%95 - 测试 }2.2.3 代码#include stdio.h #include string.h #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); } #if 0 int main(int argc, char *argv[]) { /* char url[100] http://测试/mike; urlencode(url); //编码后 printf(http://测试/mike ---- %s\n, url); char buf[100] http%3A//%27%E6%B5%8B%E8%AF%95/%40mike; urldecode(buf); //解码后 printf(http%%3A//%%27%%E6%%B5%%8B%%E8%%AF%%95/%%40mike ---- %s\n, buf); */ /* char buf[100]三1星; urlencode(buf); printf(encode %s\n,buf); */ //char url[100]%E4%B8%891%E6%98%9F; char url[100]%E4%B8%89%E6%98%9F; urldecode(url); printf(decode %s\n,url); return 0; } #endif2.3url2.h- URL处理头文件// url2.h #ifndef URL2_H #define URL2_H // URL编码函数 void urlencode(char url[]); // URL解码函数 void urldecode(char url[]); #endif简单的函数声明头文件。三、数据库设计表结构推测admin_user表用户表user_id用户ID主键user_name用户名password密码goods表商品表goods_id商品ID主键goods_name商品名称shop_price商品价格goods_brief商品简介goods_desc商品详细描述四、目录结构项目根目录/ ├── ser.c # 主服务器程序 ├── url2.c # URL编码解码 ├── url2.h # URL处理头文件 ├── 123.db # SQLite数据库 ├── html/ # HTML模板目录 │ ├── login.html │ ├── search.html │ ├── detail.html │ ├── list.html │ ├── register.html │ └── error.html └── images/ # 图片资源目录 ├── 200905/ │ ├── thumb_img/ │ ├── goods_img/ │ └── source_img/ └── no_picture.gif # 默认图片流程图五、功能特点1. 安全性考虑使用SQLite预编译语句防止SQL注入URL参数解码处理文件存在性检查2. 性能优化静态文件缓存发送分块读取发送数据库查询限制结果数量LIMIT 50连接复用设置SO_REUSEADDR3. 用户体验响应式HTML设计内联CSS图片懒加载多种尺寸图片目录友好的错误页面热门搜索推荐4. 扩展性模块化路由处理易于添加新的页面和处理函数支持多种文件类型六、编译运行编译命令gcc -o server ser.c url2.c -lsqlite3 -lpthread运行服务器./server服务器将监听8080端口http://localhost:8080七、改进建议安全性增强添加密码哈希存储当前为明文实现Session管理增加请求频率限制功能扩展添加商品分类筛选实现购物车功能添加分页支持代码优化分离路由配置到独立文件添加配置文件支持实现日志记录系统性能提升添加HTTP Keep-Alive支持实现图片缓存机制数据库连接池八、总结这是一个功能完整的C语言Web服务器项目展示了基本的HTTP服务器实现数据库操作与SQLite集成动态HTML页面生成文件系统操作URL编码解码处理

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询