实用指南:项目——基于C/S架构的预约系统平台(3)

news/2025/11/25 9:20:18/文章来源:https://www.cnblogs.com/tlnshuju/p/19266720

实用指南:项目——基于C/S架构的预约系统平台(3)

2025-11-25 09:13  tlnshuju  阅读(0)  评论(0)    收藏  举报

前言:

首先恭喜我自己!!!第一个项目初步的业务已经圆满结束

不过过程确实很凄惨....我觉得架构实现起来是最难的 往往都是跟着人家一点点码出来架构 然后一点点来回试sql的正确 感觉历经磨难...借助ai的辅助总归是把这个项目的基本业务完成了

我又稍微优化(×细分)了一下架构 给大家展示一下

ser.h

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int listenmax=10;
enum op_type{DL=1,ZC,CKYY,YD,CKYD,QXYD,TC
};
//mysql数据库操作类
class mysql_client{
public:// 默认构造函数:初始化数据库连接参数(本地数据库默认配置)mysql_client(){db_ips="127.0.0.1";db_username="root";db_dbname="project_db";db_passwd="770202";}// 析构函数:关闭数据库连接~mysql_client(){mysql_close(&mysql_con);}bool mysql_connectserver();// 参数:tel(手机号)、passwd(密码)、name(用户名)bool mysql_register(const string &tel,const string &passwd,const string &name);bool mysql_login(const string&tel,const string &passwd,string &name);// 查看可预约信息:从数据库查询预约数据,存入JSON对象// 参数:resval(输出参数,存储查询结果)bool mysql_show_ticket(Json::Value&resval);bool mysql_subscribe_ticket(int tk_id,string tel);//查看我的预约,增加函数设计参数//取消预约,增加函数设计参数bool mysql_cancel_sub_ticket(int yd_id, const string& tel);bool mysql_show_sub_ticket(const string& tel, Json::Value& resval);
private:// 事务开始(用于需要原子性的操作,如预订时减库存+记录预订)bool mysql_user_begin();// 事务提交(操作成功时确认变更)bool mysql_user_commit();// 事务回滚(操作失败时撤销变更)bool mysql_user_rollback();
private:MYSQL mysql_con;string db_ips;string db_username;string db_dbname;string db_passwd;
};
//服务器监听
class socket_listen{
public:socket_listen(){sockfd=-1;m_port=6000;m_ips="127.0.0.1";}socket_listen(string ips,short port):m_ips(ips),m_port(port){sockfd=-1;}bool socket_init();int accept_client();void set_base(struct event_base*base){this->base=base;}int getsockfd()const{return sockfd;}struct event_base* get_base()const{return base;}
private:int sockfd;short m_port;string m_ips;struct event_base * base;
};
//客户端连接处理
class socket_con{
public:socket_con(int fd):c(fd){c_ev=NULL;}void set_ev(struct event*ev){c_ev=ev;}~socket_con(){event_free(c_ev);close(c);}void recv_data();void send_err();void send_ok();void user_register();void user_login();void user_show_ticket();//查看预约信息void user_subscribe_ticket();//预订void user_cancel_sub_ticket();void user_show_sub_ticket();
private:int c;struct event* c_ev;Json::Value val;//mysql_client cli;
};

listen.cpp

#include"ser.h"
bool socket_listen::socket_init(){sockfd=socket(AF_INET,SOCK_STREAM,0);if(-1==sockfd)return false;struct sockaddr_in saddr;memset(&saddr,0,sizeof(saddr));saddr.sin_family=AF_INET;saddr.sin_port=htons(m_port);saddr.sin_addr.s_addr=inet_addr(m_ips.c_str());int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));if(-1==res){perror("绑定失败\n");close(sockfd);return false;}res=listen(sockfd,listenmax);if(res==-1)return false;return true;
}
int socket_listen::accept_client(){int c=accept(sockfd,NULL,NULL);return c;
}

ser.cpp

#include"ser.h"
//mysql_client
//socket_listen
//socket_con
void socket_con::send_err(){Json::Value res_val;res_val["status"]="ERR";send(c,res_val.toStyledString().c_str(),strlen(res_val.toStyledString().c_str()),0);
}
void socket_con::send_ok(){Json::Value res_val;res_val["status"]="OK";send(c,res_val.toStyledString().c_str(),strlen(res_val.toStyledString().c_str()),0);
}
void socket_con::user_register(){string tel,passwd,username;tel=val["user_tel"].asString();passwd=val["user_passwd"].asString();username=val["user_name"].asString();if(tel.empty()||passwd.empty()||username.empty()){send_err();return;}mysql_client cli;if(!cli.mysql_connectserver()){send_err();return;}if(!cli.mysql_register(tel,passwd,username)){send_err();return;}send_ok();return;
}
void socket_con::user_login(){string tel=val["user_tel"].asString();string passwd=val["user_passwd"].asString();string user_name;mysql_client cli;if(!cli.mysql_connectserver()){send_err();return;}if(!cli.mysql_login(tel,passwd,user_name)){send_err();return;}Json::Value res_val;res_val["status"]="OK";res_val["user_name"]=user_name;send(c,res_val.toStyledString().c_str(),strlen(res_val.toStyledString().c_str()),0);return;
}
void socket_con::user_show_ticket(){Json::Value resval;mysql_client cli;if(!cli.mysql_connectserver()){send_err();return;}if(!cli.mysql_show_ticket(resval)){send_err();return;}send(c,resval.toStyledString().c_str(),strlen(resval.toStyledString().c_str()),0);return;
}
void socket_con::user_subscribe_ticket(){//client  ->  tk_id ,telint tk_id=val["index"].asInt();string tel=val["tel"].asString();mysql_client cli;if(!cli.mysql_connectserver()){cout<<"connect mysql err"<recv_data();}
}
void SOCK_LIS_CALLBACK(int sockfd,short ev,void *arg){socket_listen* p=(socket_listen*)arg;if(p==NULL)return;if(ev&EV_READ){ //处理读事件int c=p->accept_client();if(c==-1)return;cout<<"accept:c="<get_base(),c,EV_READ|EV_PERSIST,SOCK_CON_CALLBACK,q);if(c_ev==NULL){close(c);delete q;return;}q->set_ev(c_ev);//添加到libeventevent_add(c_ev,NULL);}
}
int main(){//监听套接字socket_listen socket_ser;if(!socket_ser.socket_init()){cout<<"socket init err!"<

mysqlconnect.cpp

#include"ser.h"
bool mysql_client::mysql_connectserver(){MYSQL*mysql=mysql_init(&mysql_con);if(mysql==NULL)return false;mysql=mysql_real_connect(mysql,db_ips.c_str(),db_username.c_str(),db_passwd.c_str(),db_dbname.c_str(),3306,NULL,0);if(mysql==NULL){cout<<"connect db server err"<

接下来是客户端的

cli.h

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int offset=2;
enum op_type{DL=1,ZC,CKYY,YD,CKYD,QXYD,TC};
//客户端及具体实现功能
class socket_client{
public:socket_client(){sockfd=-1;ips="127.0.0.1";port=6000;dl_flg=false;user_op=0;runing=true;}socket_client(string ips,short port){sockfd=-1;this->ips=ips;this->port=port;dl_flg=false;user_op=0;runing=true;}void print_info();~socket_client(){close(sockfd);}bool connect_server();void user_register();void user_login();void user_show_ticket();void user_subscribe_ticket();void user_cancel_sub_ticket();void user_show_sub_ticket();void run();
private:string ips;short port;int sockfd;bool dl_flg;string username;string usertel;int user_op;bool runing;Json::Value m_val;
};

connect.cpp

#include"cli.h"
bool socket_client::connect_server(){sockfd=socket(AF_INET,SOCK_STREAM,0);if(-1==sockfd){perror("create socket err!\n");return false;}struct sockaddr_in saddr;memset(&saddr,0,sizeof(saddr));saddr.sin_family=AF_INET;saddr.sin_port=htons(port);saddr.sin_addr.s_addr=inet_addr(ips.c_str());int res=connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));if(res==-1){perror("connect ser err!\n");return false;}cout<<"connect to server success"<

cli.cpp

#include"cli.h"
void socket_client::print_info(){if(dl_flg){cout<<"--已登陆-------用户名:"<>user_op;user_op+=offset;}else{cout<<"---未登陆-----游客-----"<>user_op;if(user_op==3)user_op=TC;}
}
void socket_client::user_register(){cout<<"请输入用户手机号码:"<>usertel;cout<<"请输入用户名"<>username;string passwd,tmp;cout<<"请输入密码:"<>passwd;cout<<"请再次输入密码"<>tmp;if(usertel.empty()||username.empty()){cout<<"手机或用户名不能为空"<>tel;cout<<"请输入密码"<>passwd;if(tel.empty()||passwd.empty()){cout<<"帐号或密码不能为空"<>index;//index  有效性检查Json::Value val;val["type"]=YD;val["tel"]=usertel;val["index"]=index;send(sockfd,val.toStyledString().c_str(),strlen(val.toStyledString().c_str()),0);char buff[256]={0};int n=recv(sockfd,buff,255,0);if(n<=0){cout<<"ser close"<> yd_id;//  构建请求JSONJson::Value val;val["type"] = QXYD;val["tel"] = usertel;val["yd_id"] = yd_id;send(sockfd, val.toStyledString().c_str(), strlen(val.toStyledString().c_str()), 0);char buff[256]={0};int n=recv(sockfd,buff,255,0);if(n<=0){cout<<"ser close"<

可继续优化点:

高优先级(安全与稳定性)

1. 数据完整性问题

· send/recv数据完整性
  · 实现send_all()和recv_all()函数
  · 处理部分发送/接收的情况
  · 考虑定义应用层协议(长度头 + JSON体)

2. SQL注入防护

· 预处理语句替换字符串拼接
  · 注册功能:mysql_register()
  · 登录功能:mysql_login()
  · 票务查询:mysql_show_ticket()
  · 预订功能:mysql_subscribe_ticket()

3. 输入验证完善

· 空值检查后立即返回(已发现的问题)
· 手机号格式验证(正则表达式)
· 用户名长度限制
· 整数参数范围检查

4. 资源泄漏修复

· 数据库连接管理
  · 当前:每次操作新建连接(性能差)
  · 目标:实现连接池
· 内存泄漏检查
  · socket_con对象的生命周期管理
  · MySQL结果集释放mysql_free_result()

中优先级(性能与用户体验)

5. 非阻塞IO改造

· 服务端socket设为非阻塞
· 客户端socket设为非阻塞
· 处理EAGAIN/EWOULDBLOCK错误码
· 实现IO多路复用的完整优势

6. Libevent性能优化

· 升级到Libevent2新API
· 启用ET边缘触发模式
· 配置高性能事件驱动后端

7. 数据库优化

· 连接池实现
· 为常用查询字段添加索引
· 查询结果缓存机制

8. 错误信息细化

· 区分不同错误类型:
  · 用户已存在
  · 密码错误
  · 票已售完
  · 数据库连接失败
· 返回具体错误码和描述

低优先级(代码质量与扩展性)

9. 代码结构优化

· 配置文件外部化
  · 数据库连接参数
  · 服务器端口配置
· 日志系统完善
· 统一错误处理机制

10. 安全增强

· 密码加密传输(MD5/SHA1)
· 敏感信息脱敏
· 请求频率限制

11. 协议优化

· 二进制协议替代JSON(可选)
· 数据压缩
· 心跳包机制

具体实施计划

Phase 1:安全与稳定性(预计2-3天)

```
1. 数据完整性 → 2. SQL注入防护 → 3. 输入验证 → 4. 资源泄漏
```

Phase 2:性能优化(预计3-4天)

```
5. 非阻塞IO → 6. Libevent优化 → 7. 数据库连接池
```

Phase 3:用户体验(预计1-2天)

```
8. 错误信息细化 → 9. 配置外部化
```

业务逻辑优化

· 重复查询优化:user_subscribe_ticket()中先调用了user_show_ticket()
· 事务边界细化:某些查询操作不需要事务
· 数据验证前置:客户端先做基础验证,减少服务端压力

 客户端体验

· 输入错误处理:类型转换异常处理
· 操作确认:重要操作前的确认提示
· 结果展示优化:表格格式化输出

总结:

sql注入的风险还是很大的 所以有时间需要修改一下那里。让ai预测了一下并发数量 它预测支持几十个让我有点破防 但是我压力测试了一下发现能达到一千多(甚至是因为mysql的连接量满的原因)所以还是超过我的预期的  遇到的困难很多哎 比如sql语句的描述 json的序列化反序列 还有n多的参数记不住。。。总而言之ai帮了大忙(

哎简单来说毕竟这是从0到1的跨越嘛~再多做几个玩具就能游龙了吧(应该?  第一阶段的预约系统就到这里啦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/975579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

# vue3 使用 echarts 展示某省份各区市数据

vue3 使用 echarts 展示某省份各区市数据这个很简单,直接贴代码了代码 echarts 使用的是最新版:"echarts": "^6.0.0"。 <template><div class="ed-map-div"><div clas…

2025年评价高的罐头塑料瓶厂家最新热销排行

2025年评价高的罐头塑料瓶厂家最新热销排行行业背景与市场趋势随着全球食品工业的持续发展和消费者对食品安全要求的不断提高,罐头塑料瓶作为食品包装的重要形式,正经历着前所未有的技术革新与市场扩张。根据中国包装…

MATLAB决策树仿真代码(分类与回归)

一、分类树实现(基于CART算法) 数据集:使用MATLAB内置的鸢尾花(Iris)数据集,实现三分类任务 核心步骤:数据加载→特征标准化→模型训练→可视化→性能评估 %% 1. 数据加载与预处理 load fisheriris; % 加载数据…

2025 年 11 月角接触球轴承厂家权威推荐榜:覆盖电主轴/超高速/光伏专用/切片机/高低噪音等全场景精密轴承优选指南

2025 年 11 月角接触球轴承厂家权威推荐榜:覆盖电主轴/超高速/光伏专用/切片机/高低噪音等全场景精密轴承优选指南 行业背景与发展趋势 角接触球轴承作为精密机械装备的核心基础件,其性能直接影响着机床加工精度、电…

2025 年 11 月低阻力 / 双止回阀 / 不锈钢倒流防止器厂家最新推荐:上海上龙供水设备有限公司技术标杆与选型指南

在给排水、水利工程、化工等领域,倒流防止器作为保障管道介质单向流动、杜绝回流污染的核心设备,其性能直接关系到系统安全与水质保障。随着行业需求逐年攀升,市场对低阻力、高密封、长寿命的倒流防止器产品需求愈发…

英国留学机构十大排名重磅出炉,英国留学机构怎么选?唯寻国际教育首当其冲

近年来,英国留学凭借顶尖的教育资源、灵活的申请政策和广阔的就业前景,成为中国学子留学的首选目的地之一。从 G5 超级精英大学到罗素集团名校,每年都有无数同学为了 “英伦梦” 全力以赴,但选对一家靠谱的留学机构…

2025年11月油浸式变压器、干式变压器、电力设备、电气设备、电器设备生产厂家综合实力排行榜:专业选购指南与行业解析

摘要 随着2025年国内电力设备行业的快速发展,干式变压器作为关键电力设备,其市场需求持续增长。本文基于行业数据、技术实力、市场口碑等多维度分析,为您呈现2025年11月干式变压器厂家综合排名,并提供专业选购建议…

2025年靠谱的宠物罐塑料瓶厂家推荐及选购指南

2025年靠谱的宠物罐塑料瓶厂家推荐及选购指南行业背景与市场趋势随着宠物经济的蓬勃发展,全球宠物食品包装市场规模预计将在2025年达到85亿美元,年复合增长率达6.2%(数据来源:Smithers Pira市场研究报告)。在这一…

告别硬编码!Spring Boot 配置绑定原来可以这么玩,优雅到飞起!

在业务系统迁移改造中,你是否也遇到过这样的场景:项目里充斥着Properties.load()的硬编码,配置文件的key和对象属性靠手动getProperty逐个绑定,一旦配置项增多,不仅写起来繁琐,改起来更是心惊胆战——生怕漏填一…

1104. Sum of Number Segments (20)

1104. Sum of Number Segments (20)#include <iostream>using namespace std;double num[100010];int main() {int n;scanf("%d", &n);int i;for(i = 1; i <= n; i++){scanf("%lf", …

1105. Spiral Matrix (25)

1105. Spiral Matrix (25)#include <iostream> #include <algorithm> #include <algorithm>using namespace std;int num[10010], arr[110][110];int cmp(int a, int b) {return a > b; }int mai…

1111. Online Map (30)

1111. Online Map (30)#include <iostream> #include <vector> #include <string.h>using namespace std;struct node {int next, length, time; };void print(vector<int> v) {int size = v.…

1106. Lowest Price in Supply Chain (25)

1106. Lowest Price in Supply Chain (25)#include <iostream> #include <vector> #include <queue>using namespace std;double p, r; vector<int> v[100010]; queue<int> q; int flag…

大概率上涨的股票2025年11月25日09:07

根据提供的两个CSV文件(merged.csv和merged1.csv)的数据,我整合了所有记录,并针对每个股票计算了以下指标:平均上涨概率:仅基于预测为“涨”的记录的概率平均值。 预测次数:该股票被预测的总次数(包括涨和跌)…

2025年热门的木盘托盘品牌厂家排行榜

2025年热门的木盘托盘品牌厂家排行榜:品质与创新的行业标杆木盘托盘行业背景与市场趋势近年来,随着环保意识的提升和消费升级的推动,木质包装及家居用品市场呈现持续增长态势。据中国林产工业协会最新数据显示,202…

1121. Damn Single (25)

1121. Damn Single (25)#include <iostream> #include <algorithm> #include <vector> #include <string.h>using namespace std;int couple[100000], party[100000], num[100000];int main()…

1122. Hamiltonian Cycle (25)

1122. Hamiltonian Cycle (25)#include <iostream> #include <string.h>using namespace std;int path[210][210];int main() {int n, m;scanf("%d%d", &n, &m);int i, a, b;for(i = 1;…

1123. Is It a Complete AVL Tree (30)

1123. Is It a Complete AVL Tree (30)#include <iostream> #include <stdlib.h> #include <queue>using namespace std;typedef struct node {int key, bf;struct node *lchild, *rchild; }*bnode;…

2025年11月25日最新更新:四川靠谱的电线电缆供应厂家综合评估与选购指南

摘要 随着四川省基础设施建设和新能源产业的快速发展,电线电缆行业在2025年迎来了新的发展机遇。本文基于市场调研和行业数据,为您推荐五家值得关注的四川电线电缆供应厂家,排名不分先后,仅供参考。特别说明,本文…

docker网络端口占用自适应

1. 动态端口分配 不指定主机端口,让Docker自动分配 docker run -d -p 80 nginx # 主机端口随机分配 docker run -d -p 80 nginx # 另一个容器也会分配不同端口 查看分配的端口 docker ps 2. 指定不同主机端口 手动指…