一、数据库设计
本节课在上一节课的 JSON 通信框架上引入数据库,主要实现用户注册数据的存储和查询。
1. 数据库表设计
user_info 表
| 字段名 | 类型 | 约束与意义 |
|---|---|---|
| tel_id | CHAR(11) | 主键、非空、唯一,手机号(用户ID) |
| name | VARCHAR(20) | 用户名 |
| passwd | VARCHAR(16) | 密码 |
| status | TINYINT | 状态标记(0 = 禁用 / 1 = 启用) |
SQL 创建语句:
CREATE TABLE user_info(
tel_id CHAR(11) PRIMARY KEY NOT NULL UNIQUE,
name VARCHAR(20),
passwd VARCHAR(16),
status TINYINT
);
query_res 表
| 字段名 | 类型 | 约束与意义 |
|---|---|---|
| id | 主键 | |
| res_id | 预约 ID | |
| 是否使用过 | 标记是否使用 |
ticket_table 表
| 字段名 | 类型 | 约束与意义 |
|---|---|---|
| res_id | 资源 ID | |
| res_name | 资源名称 | |
| 总数目 | 总数量 | |
| 已使用 | 已使用数量 | |
| 是否开启预约 | 是否可预约 |
二、客户端流程
客户端通过 client.cpp 实现注册、登录、预约等操作。
1. 连接服务器
bool Client::ConnectToServer()
{
sockfd = socket(AF_INET,SOCK_STREAM,0);
...
connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
...
}
-
成功连接服务器后才能进行后续操作
-
套接字命名、端口设置和 IP 地址配置
2. 用户交互
-
Print_Info()根据登录状态显示菜单:-
未登录:1 登录 2 注册
-
已登录:1 预约 2 查看 3 取消预约 4 退出
-
-
选项偏移处理:已登录选项编号 +2,避免和未登录冲突
3. 注册操作
Zc_user() 主要流程:
-
从键盘读取手机号、用户名、密码
-
组装 JSON 请求:
{
"type": "ZC",
"user_tel": "13900000001",
"user_name": "小红",
"user_passwd": "111111"
}
- 发送给服务器:
send(sockfd,val.toStyledString().c_str(),strlen(val.toStyledString().c_str()),0);
- 接收服务器返回 JSON:
recv(sockfd, res_buff, 127, 0);
- 解析 JSON 并判断状态:
zc_status = val["status"].asString();
if(zc_status == "OK") cout << "注册成功" << endl;
三、服务端流程
服务端通过 server.cpp + libevent + 回调类 完成 JSON 消息处理和数据库操作。
1. 监听套接字 Lis_Socket
- 创建、绑定、监听套接字:
socket()
bind()
listen()
- 为客户端连接提供"入口"
2. 事件管理 LibEvent
-
初始化事件系统:
Init() -
注册文件描述符和回调:
Lib_Add(fd, callback) -
启动事件循环:
Dispatch()
3. 回调类体系
| 类名 | 功能描述 |
|---|---|
CallBack |
抽象回调基类,定义接口 CallBack_Fun() |
Accept_CallBack |
监听套接字事件,新客户端接入,注册连接套接字 |
Recv_CallBack |
连接套接字事件,处理 JSON 数据收发与业务逻辑 |
4. JSON 解析与业务处理
- 使用
jsoncpp:
Json::Value val;
Json::Reader reader;
reader.parse(buff, val);
- 消息类型判断:
if(val["type"]=="ZC") Zc_User();
else if(val["type"]=="DL") Dl_User();
...
- 注册用户存数据库:
string sql = "insert into user_info values('"+tel+"','"+name+"','"+passwd+"','1')";
mysqlcli.Query_sql(sql);
Send_ok();
- 登录验证数据库:
string sql = "SELECT * FROM user_info WHERE tel_id='"+tel+"' AND passwd='"+passwd+"'";
mysqlClient.Query_sql(sql);
四、客户端 → 服务器 → 数据库 → 客户端 流程图(文字版)
-
客户端输入手机号、用户名、密码
-
客户端组装 JSON 请求发送服务器
-
服务器触发
Recv_CallBack:-
接收 JSON
-
解析
type -
调用
Zc_User()或Dl_User()
-
-
操作数据库:
-
注册:插入
user_info表 -
登录:查询
user_info表
-
-
返回 JSON 状态
{ "status": "OK"/"ERROR" } -
客户端解析返回 JSON 并显示结果
五、本节课核心知识点
-
数据库接入
-
数据存储从内存升级到 MySQL
-
注册和登录操作持久化
-
-
JSON 协议通信
-
客户端按协议发送 JSON
-
服务器解析 JSON 并返回 JSON
-
-
事件驱动 + 面向对象设计
-
Lis_Socket封装套接字 -
LibEvent负责事件调度 -
回调类处理具体业务
-
-
协议设计意识
-
type字段区分业务类型(注册/登录/预约) -
按协议收发数据,方便扩展
-

一、创建用户信息表 user_info

1. 执行建表 SQL
CREATE TABLE user_info(
tel_id CHAR(11) PRIMARY KEY NOT NULL UNIQUE,
name VARCHAR(20),
passwd VARCHAR(16),
status TINYINT
);
2. 字段说明
| 字段名 | 类型 | 约束与含义 |
|---|---|---|
tel_id |
CHAR(11) | 主键、非空、唯一 → 手机号(用户 ID) |
name |
VARCHAR(20) | 用户名 |
passwd |
VARCHAR(16) | 密码 |
status |
TINYINT | 状态标记(如 0 = 禁用 / 1 = 启用) |
3. 执行结果
Query OK, 0 rows affected (0.01 sec)
✅ 表创建成功,当前无数据。
做一个测试



