2.11 sqlite3数据库【数据库的相关操作指令、函数】

练习:
将 epoll 服务器 客户端拿来用
客户端:写一个界面,里面有注册登录
服务器:处理注册和登录逻辑,注册的话将注册的账号密码写入数据库,登录的话查询数据库中是否存在账号,并验证密码是否正确
额外功能:客户端登录的时候,服务器向客户端发送一个验证码,只有验证码也正确的时候,才能登录成功·
server.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sqlite3.h>
#include <errno.h>
#include <time.h>#define MAX_EVENTS 100typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;enum Type {TYPE_REGIST,TYPE_LOGIN,TYPE_CHAT
};typedef struct Pack {enum Type type;char name[20];char pswd[20];char tarname[20];char text[1024];
} pack_t;sqlite3 *db; // 数据库指针// 生成验证码
void generate_code(char *code, int length) {const char charset[] = "0123456789";srand(time(NULL));for (int i = 0; i < length; i++) {code[i] = charset[rand() % 10];}code[length] = '\0';
}// 设置文件描述符非阻塞模式
void set_nonblocking(int fd) {int flags = fcntl(fd, F_GETFL, 0);fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}// 处理客户端请求
void handle_client(int client) {pack_t pack = {0};int res = read(client, &pack, sizeof(pack));if (res <= 0) {printf("客户端断开连接\n");close(client);return;}char sql[256];char *errmsg = NULL;switch (pack.type) {case TYPE_REGIST:snprintf(sql, sizeof(sql), "INSERT INTO users (name, password) VALUES ('%s', '%s');", pack.name, pack.pswd);if (sqlite3_exec(db, sql, 0, 0, &errmsg) != SQLITE_OK) {printf("注册失败: %s\n", errmsg);strcpy(pack.text, "注册失败,该账号可能已存在!");sqlite3_free(errmsg);} else {strcpy(pack.text, "注册成功!");}write(client, &pack, sizeof(pack));break;case TYPE_LOGIN: {snprintf(sql, sizeof(sql), "SELECT password FROM users WHERE name = '%s';", pack.name);sqlite3_stmt *stmt;if (sqlite3_prepare_v2(db, sql, -1, &stmt, 0) == SQLITE_OK) {if (sqlite3_step(stmt) == SQLITE_ROW) {const char *db_pswd = (const char*)sqlite3_column_text(stmt, 0);if (strcmp(db_pswd, pack.pswd) == 0) {char code[6];generate_code(code, 5);snprintf(pack.text, sizeof(pack.text), "验证码:%s\n", code);write(client, &pack, sizeof(pack));// 等待客户端输入验证码read(client, &pack, sizeof(pack));if (strcmp(pack.text, code) == 0) {strcpy(pack.text, "登录成功!");} else {strcpy(pack.text, "验证码错误,登录失败!");}} else {strcpy(pack.text, "密码错误!");}} else {strcpy(pack.text, "账号不存在!");}sqlite3_finalize(stmt);}write(client, &pack, sizeof(pack));break;}case TYPE_CHAT:printf("收到消息: %s\n", pack.text);break;}
}int main(int argc, const char *argv[]) {if (argc != 2) {printf("请输入端口号\n");return 1;}int port = atoi(argv[1]);// 初始化数据库if (sqlite3_open("users.db", &db) != SQLITE_OK) {printf("无法打开数据库\n");return 1;}const char *create_table_sql = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT UNIQUE, password TEXT);";char *errmsg = NULL;if (sqlite3_exec(db, create_table_sql, 0, 0, &errmsg) != SQLITE_OK) {printf("创建表失败: %s\n", errmsg);sqlite3_free(errmsg);return 1;}// 创建服务器 socketint server = socket(AF_INET, SOCK_STREAM, 0);addr_in_t addr = {0};addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = INADDR_ANY;bind(server, (addr_t*)&addr, sizeof(addr));listen(server, 10);// 设置非阻塞模式set_nonblocking(server);// 创建 epollint epoll_fd = epoll_create1(0);struct epoll_event ev, events[MAX_EVENTS];ev.events = EPOLLIN;ev.data.fd = server;epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server, &ev);printf("服务器启动,监听端口 %d...\n", port);while (1) {int n = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);for (int i = 0; i < n; i++) {if (events[i].data.fd == server) {// 处理新连接int client = accept(server, NULL, NULL);if (client < 0) {perror("accept");continue;}set_nonblocking(client);ev.events = EPOLLIN | EPOLLET;ev.data.fd = client;epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client, &ev);printf("新客户端连接: %d\n", client);} else {// 处理客户端请求handle_client(events[i].data.fd);}}}sqlite3_close(db);close(server);return 0;
}
client.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;enum Type {TYPE_REGIST,TYPE_LOGIN,TYPE_CHAT
};typedef struct Pack {enum Type type;char name[20];char pswd[20];char tarname[20];char text[1024];
} pack_t;void handle_response(int client) {pack_t pack;int res = read(client, &pack, sizeof(pack));if (res > 0) {printf("服务器: %s\n", pack.text);}
}int main(int argc, const char *argv[]) {if (argc != 2) {printf("输入端口号\n");return 1;}int port = atoi(argv[1]);int client = socket(AF_INET, SOCK_STREAM, 0);addr_in_t addr = {0};addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr("192.168.126.245");if (connect(client, (addr_t*)&addr, sizeof(addr)) == -1) {perror("连接失败");return 1;}printf("连接服务器成功!\n");while (1) {int ch;printf("1: 注册\n2: 登录\n3: 聊天\n0: 退出\n请选择: ");scanf("%d", &ch);while (getchar() != '\n');pack_t pack = {0};switch (ch) {case 1:printf("输入账号: ");scanf("%s", pack.name);while (getchar() != '\n');printf("输入密码: ");scanf("%s", pack.pswd);while (getchar() != '\n');pack.type = TYPE_REGIST;write(client, &pack, sizeof(pack));handle_response(client);break;case 2:printf("输入账号: ");scanf("%s", pack.name);while (getchar() != '\n');printf("输入密码: ");scanf("%s", pack.pswd);while (getchar() != '\n');pack.type = TYPE_LOGIN;write(client, &pack, sizeof(pack));handle_response(client); // 服务器发送验证码printf("输入验证码: ");scanf("%s", pack.text);while (getchar() != '\n');write(client, &pack, sizeof(pack));handle_response(client); // 登录成功 or 失败break;case 3:printf("输入聊天对象: ");scanf("%s", pack.tarname);while (getchar() != '\n');printf("输入消息: ");fgets(pack.text, sizeof(pack.text), stdin);pack.text[strcspn(pack.text, "\n")] = '\0'; // 去除换行符pack.type = TYPE_CHAT;write(client, &pack, sizeof(pack));handle_response(client);break;case 0:close(client);return 0;default:printf("无效选项\n");}}return 0;
}
相关文章:
2.11 sqlite3数据库【数据库的相关操作指令、函数】
练习: 将 epoll 服务器 客户端拿来用 客户端:写一个界面,里面有注册登录 服务器:处理注册和登录逻辑,注册的话将注册的账号密码写入数据库,登录的话查询数据库中是否存在账号,并验证密码是否正确…...
当 LSTM 遇上 ARIMA!!
大家好,我是小青 ARIMA 和 LSTM 是两种常用于时间序列预测的模型,各有优劣。 ARIMA 擅长捕捉线性关系,而 LSTM 擅长处理非线性和长时间依赖的关系。将ARIMA 和 LSTM 融合,可以充分发挥它们各自的优势,构建更强大的时…...
kali连接xshell
1.先保证宿主机:以太网适配器 VMware Network Adapter VMnet8 和kali(net 模式)在同一个网段 windows VMnet8开启 查看是否是自动获取ip ipv4 和ipv6一样的 查看 windows VMnet8的IPv4的地址 查看 kali 的IP地址 window ping的结果…...
图像曲率滤波
看到这么一个非常有意思的东西,记录一下 https://www.zhihu.com/question/35499791 https://zhuanlan.zhihu.com/p/22971865 GCFilter_talk.pdf_免费高速下载|百度网盘-分享无限制 https://github.com/YuanhaoGong/CurvatureFilter?tabreadme-ov-file...
TCP 和 UDP 可以绑定相同的端口吗?
前言 当一个网络接口接收到一个数据报时,IP 模块首先检查目的地址是否为自己的 IP 地址,如果是的话,数据报交付给由 IPv4 头部的协议字段指定的协议模块。 TCP 和 UDP 在内核中是两个完全独立的模块,送给 TCP/UDP 模块的报文根据…...
【Python网络爬虫】爬取网站图片实战
【Python网络爬虫】爬取网站图片实战 Scrapying Images on Website in Action By Jackson@ML *声明:本文简要介绍如何利用Python爬取网站数据图片,仅供学习交流。如涉及敏感图片或者违禁事项,请注意规避;笔者不承担相关责任。 1. 创建Python项目 1) 获取和安装最新版…...
2024年博客之星年度评选—创作影响力评审+主题文章创作评审目前排名(2024博客之星陪跑小分队助力2024博客之星创作者成长)
2024年博客之星年度评选—创作影响力评审主题文章创作评审目前排名 2024年博客之星主题文章创作评审文章得分公布!2024年博客之星创作影响力评审2024年博客之星主题文章创作评审目前排名公布! 【2024博客之星】恭喜完成✅主题创作的226位博主࿰…...
【CLIP系列】4:目标检测(ViLD、GLIP)
目录 1 ViLD2 GLIP2.1 前言2.2 损失计算2.3 模型框架 1 ViLD OPEN-VOCABULARY OBJECT DETECTION VIA VISION AND LANGUAGE KNOWLEDGE DISTILLATION 从标题就能看出来,作者是把CLIP模型当成一个Teacher,去蒸馏他自己的网络,从而能Zero Shot去…...
Qt Designer菜鸟使用教程(实现一个本地英文翻译软件)
1 安装Qt Designer 安装这个包的时候会自带安装 Qt Designer, 安装目录为python的安装根目录的 Lib/site-packages/qt5_applications/Qt/bin 目录下。 pip install pyqt5-tools2 新建窗体 2.1 新建主窗体 创建之后如下图: 设置主窗口大小: 设置窗…...
【一文读懂】HTTP与Websocket协议
HTTP协议 概述 HTTP (Hypertext Transfer Protocol),即超文本传输协议,是一种用于在客户端和服务器之间传输超文本(例如网页、图片、音频、视频等)的通信协议。它是万维网(WWW)的基础,负责在浏…...
大语言模型入门
大语言模型入门 1 大语言模型步骤1.1 pre-training 预训练1.1.1 从网上爬数据1.1.2 tokenization1.1.2.1 tokenization using byte pair encoding 1.3 预训练1.3.1 context1.3.2 training1.3.3 输出 1.2 post-training1.2.1 token 1.2 SFT监督微调1.3 人类反馈强化学习1.3.1 人…...
SQL 大厂面试题目(由浅入深)
今天给大家带来一份大厂SQL面试覆盖:基础语法 → 复杂查询 → 性能优化 → 架构设计,大家需深入理解执行原理并熟悉实际业务场景的解决方案。 1. 基础查询与过滤 题目:查询 employees 表中所有薪资(salary)大于 10000…...
Shader Step和frac函数
Step又称为阶跃函数,在着色器(Shader)编程中,step 函数是一个非常有用的函数,尤其是在GLSL(OpenGL Shading Language)和其他类似的着色器语言中。它用于生成基于阈值的阶跃函数输出。step 函数的…...
FreeRtos实时系统: 十二.FreeRTOS的队列集
FreeRtos实时系统: 十二.FreeRTOS的队列集 一.队列集简介二.队列集相关API函数三.队列集操作实验 一.队列集简介 左边的接收任务会在没接收到队列时会阻塞,如果前面释放信号量这时该任务也获取不到信号量。 右边使用队列集如果获取到,判断句柄是谁&#…...
NLP Word Embeddings
Word representation One-hot形式 在上一周介绍RNN类模型时,使用了One-hot向量来表示单词的方式。它的缺点是将每个单词视为独立的,算法很难学习到单词之间的关系。 比如下面的例子,即使语言模型已经知道orange juice是常用组合词…...
如何在24GB的GPU上运行DeepSeek-R1-Distill-Qwen-32B
如何在24GB的GPU上运行DeepSeek-R1-Distill-Qwen-32B 一、背景二、解决方案三、操作步骤1.下载模型2.安装依赖3.量化4.生成推理代码5.运行A.缓存上限为128条B.不限制缓存上限C.输出内容 一、背景 随着深度学习的不断发展,大型语言模型(LLM,L…...
2025年二级建造师报名流程图解
2025年二级建造师报名时间!附报名流程! ⏰️已公布25年二建考试时间的省份如下: ️4月19日、20日考试的城市有:贵州 ️5月10日、11日考试的城市有:湖北、陕西、宁夏、甘肃、福建、浙江、江西、黑龙江、河南、湖南、…...
深入浅出:Python 中的异步编程与协程
引言 大家好,今天我们来聊聊 异步编程 和 协程,这是近年来编程语言领域中的热点话题之一,尤其在 Python 中,它作为一种全新的编程模型,已经成为处理 IO密集型 任务的强力工具。尽管很多人对异步编程望而却步࿰…...
八大排序——简单选择排序
目录 1.1基本操作: 1.2动态图: 1.3代码: 代码解释 1. main 方法 2. selectSort 方法 示例运行过程 初始数组 每轮排序后的数组 最终排序结果 代码总结 1.1基本操作: 选择排序(select sorting)也…...
vue使用CSS布局技术,实现div定位到页面底部或顶部并居中功能
<template> <div > <div class"bottom-element"> 我在底部,并居中了 </div> </div> </template> 使用CSS布局技术,通过设置CSS属性来实现页面底部定位。 <style lang"scs…...
AC鸭的温度墙
题目描述AC鸭在实验室里看到了一面很长的温度墙,这面墙从左到右一共有 n 个位置。一开始,每个位置的温度都是 0。接下来 AC鸭会进行 m 次加热操作。每次操作给出 l,r,v表示把第l个位置到第r个位置的温度都加上上v。所有操作结束后,AC鸭想知道…...
AI Agent自动化修复GitHub Issue:从问题定位到PR提交全流程解析
1. 项目概述:一个能自动修复GitHub Issue并提交PR的AI技能 最近在折腾AI编程助手的时候,发现了一个挺有意思的东西,叫 issue-to-pr 。简单来说,这玩意儿是一个AI Agent的“技能包”,你把它装在你的AI编程工具&#…...
从通信原理到Verilog:一个约束长度7的卷积码编码器是如何炼成的?
从通信原理到Verilog:一个约束长度7的卷积码编码器是如何炼成的? 在数字通信系统的设计中,纠错编码技术如同隐形的守护者,确保数据在嘈杂信道中可靠传输。卷积码因其优异的纠错性能和简洁的编码结构,成为卫星通信、深空…...
SPSS数据合并避坑指南:键变量设置、缺失值处理与常见错误解析
SPSS数据合并实战避坑手册:从原理到解决方案 数据合并是SPSS分析过程中最基础也最容易出错的环节之一。许多用户在按照网络教程操作后,常常发现合并结果与预期不符——变量丢失、数据错乱、大量缺失值涌现。这些问题往往源于对合并原理的理解不足和关键细…...
别急着格式化!系统崩溃进不去,用这招在Win10恢复环境里解锁BitLocker加密盘
系统崩溃后抢救BitLocker加密数据的终极指南 当Windows系统突然崩溃无法启动,而你的重要数据又存放在BitLocker加密的磁盘中时,那种焦虑感是难以言喻的。很多人第一反应是重装系统或格式化硬盘,但这往往会导致永久性数据丢失。本文将带你深入…...
告别语法冲突!用SLR分析法搞定编译原理中的移进/归约难题(附FOLLOW集实战)
告别语法冲突!用SLR分析法搞定编译原理中的移进/归约难题(附FOLLOW集实战) 当你第一次尝试构建LR(0)分析表时,是否遇到过这样的报错:"状态I2存在移进/归约冲突"?这种既想移进又想归约的矛盾&…...
别再纠结剪胀角了!用Abaqus CAE五分钟搞定库伦摩尔模型的材料卡设置(含黏土/砂土参数模板)
别再纠结剪胀角了!用Abaqus CAE五分钟搞定库伦摩尔模型的材料卡设置(含黏土/砂土参数模板) 岩土工程仿真中,材料参数设置往往是新手的第一道门槛。当你在Abaqus中面对十几个输入框时,是否也曾困惑:摩擦角和…...
FPGA与CPLD在数字机顶盒中的关键技术应用
1. 可编程逻辑器件在数字机顶盒中的核心价值 数字机顶盒作为连接广播网络与终端显示设备的关键枢纽,其设计面临三大核心挑战:多标准兼容性、快速功能迭代和成本控制。Xilinx Spartan系列FPGA和CoolRunner CPLD通过硬件可重构特性,为这些挑战提…...
Win10/Win11网络适配器‘罢工’终极排查指南:从驱动、服务到协议栈的完整修复流程
Win10/Win11网络适配器深度修复指南:从驱动到协议栈的全面诊断 当你的Windows设备突然无法联网,只剩下孤零零的飞行模式图标时,那种焦虑感每个IT从业者都深有体会。上周我的主力开发机就遭遇了这样的"罢工"事件——所有网络连接突然…...
ESP32-CAM上传图片总失败?排查HTTP POST到巴法云的5个常见坑(WiFi、电源、引脚)
ESP32-CAM图片上传失败排查指南:从硬件到平台的5大关键点 当你满怀期待地将ESP32-CAM对准拍摄对象,却发现图片始终无法上传到巴法云时,那种挫败感我深有体会。这不是一个简单的"复制粘贴代码就能运行"的项目,而是一个需…...
