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…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...