02.11 数据库

news2025/2/12 23:48:25

1.思维导图

2.题目

  • 将 epoll 服务器、客户端拿来用
  • 客户端:写一个界面,里面有注册登录
  • 服务器:处理注册和登录逻辑,注册的话将注册的账号密码写入数据库,登录的话查询数据库中是否存在账号,并验证密码是否正确

服务器代码

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
#include <sqlite3.h>
#include <sys/epoll.h>

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_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;

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;
    }

    // 创建服务器套接字
    int server = socket(AF_INET, SOCK_STREAM, 0);

    // 准备网络地址结构体:struct sockaddr_in
    addr_in_t addr = {0};
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr("0.0.0.0");

    // 为套接字绑定 ip 和 port
    if (bind(server, (addr_t *)&addr, sizeof(addr)) == -1) {
        perror("bind");
        return 1;
    }

    // 监听
    listen(server, 10);

    // 创建epoll实例
    int epfd = epoll_create1(EPOLL_CLOEXEC);
    if (epfd == -1) {
        perror("epoll_create1");
        return 1;
    }

    // 注册服务器套接字到epoll
    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = server;
    if (epoll_ctl(epfd, EPOLL_CTL_ADD, server, &event) == -1) {
        perror("epoll_ctl add server");
        return 1;
    }

    struct epoll_event active_events[100];
    while (1) {
        int num_events = epoll_wait(epfd, active_events, 100, -1);
        if (num_events == -1) {
            perror("epoll_wait");
            break;
        }

        for (int i = 0; i < num_events; i++) {
            if (active_events[i].data.fd == server) {
                // 有新客户端连接
                printf("有新客户端连接\n");
                int client = accept(server, NULL, NULL);
                if (client == -1) {
                    perror("accept");
                    continue;
                }

                event.events = EPOLLIN;
                event.data.fd = client;
                if (epoll_ctl(epfd, EPOLL_CTL_ADD, client, &event) == -1) {
                    perror("epoll_ctl add client");
                    close(client);
                }
            } else {
                // 处理客户端数据
                int client = active_events[i].data.fd;
                pack_t pack = {0};
                int res = read(client, &pack, sizeof(pack));
                if (res <= 0) {
                    printf("客户端断开连接\n");
                    close(client);
                    if (epoll_ctl(epfd, EPOLL_CTL_DEL, client, NULL) == -1) {
                        perror("epoll_ctl del client");
                    }
                    continue;
                }

                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) {
                                    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;
                }
            }
        }
    }

    close(server);
    close(epfd);
    sqlite3_close(db);
    return 0;
}

客户端代码

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_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_server_message(int client) {
    pack_t pack = {0};
    int res = read(client, &pack, sizeof(pack));
    if (res <= 0) {
        printf("服务器断开连接\n");
        exit(EXIT_SUCCESS);
    }
    printf("%s\n", pack.text);
}

// 处理用户输入
void handle_user_input(int client) {
    int ch;
    printf("1: 注册\n2: 登录\n3: 退出\n选择:");
    scanf("%d", &ch);
    while (getchar() != '\n');

    pack_t pack = {0};
    if (ch == 1 || ch == 2) {
        printf("输入账号: ");
        scanf("%s", pack.name);
        while (getchar() != '\n');
        printf("输入密码: ");
        scanf("%s", pack.pswd);
        while (getchar() != '\n');

        pack.type = (ch == 1) ? TYPE_REGIST : TYPE_LOGIN;
        write(client, &pack, sizeof(pack));
    } else {
        close(client);
        exit(EXIT_SUCCESS);
    }
}

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.110.87");

    if (connect(client, (addr_t*)&addr, sizeof(addr)) == -1) {
        perror("连接失败");
        return 1;
    }

    // 创建 epoll 实例
    int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
    if (epoll_fd == -1) {
        perror("epoll_create1");
        return 1;
    }

    // 将客户端套接字和标准输入添加到 epoll 实例中
    struct epoll_event ev, events[2];
    ev.events = EPOLLIN;
    ev.data.fd = client;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client, &ev) == -1) {
        perror("epoll_ctl: client");
        return 1;
    }

    ev.data.fd = STDIN_FILENO;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) == -1) {
        perror("epoll_ctl: stdin");
        return 1;
    }

    while (1) {
        int nfds = epoll_wait(epoll_fd, events, 2, -1);
        if (nfds == -1) {
            perror("epoll_wait");
            continue;
        }

        for (int i = 0; i < nfds; i++) {
            if (events[i].data.fd == client) {
                // 处理服务器消息
                handle_server_message(client);
            } else if (events[i].data.fd == STDIN_FILENO) {
                // 处理用户输入
                handle_user_input(client);
            }
        }
    }

    close(epoll_fd);
    close(client);
    return 0;
}

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

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

相关文章

Spring Boot整合DeepSeek实现AI对话(API调用和本地部署)

本篇文章会分基于DeepSeek开放平台上的API&#xff0c;以及本地私有化部署DeepSeek R1模型两种方式来整合使用。 本地化私有部署可以参考这篇博文 全面认识了解DeepSeek利用ollama在本地部署、使用和体验deepseek-r1大模型 Spring版本选择 根据Spring官网的描述 Spring AI是一…

苹果转型独立AR眼镜:一场技术与创新的深度探索

在科技日新月异的今天,增强现实(AR)技术正逐渐从科幻电影走进我们的日常生活。作为科技界的领头羊,苹果公司的每一步动向都备受关注。近期,苹果宣布暂停原定的Mac连接式AR眼镜计划,转而全力研发一款独立的AR眼镜。这一战略调整不仅反映了苹果对AR市场的深度洞察,也预示着…

Java小白入门基础知识(一)

1.初识Java java源程序通过javac 编译生成字节码文件&#xff0c;通过java命令运行java程序 总结&#xff1a; 1&#xff09;在一个Java文件中&#xff0c;只能有一个public class 2&#xff09;public class一定要和文件名一致 3&#xff09;类里面包含方法 4&#xff09…

通过 Docker 安装和部署 KeyDB v6.3.4 的详细步骤

KeyDB 是一种高性能的开源内存数据库&#xff0c;最初是基于 Redis 项目开发的&#xff0c;但在性能、特性和功能上进行了许多增强和改进。它兼容 Redis 的大部分命令和数据结构&#xff0c;因此可以作为 Redis 的替代品使用&#xff0c;尤其是在需要更高性能和多线程支持的场景…

【JavaEE进阶】依赖注入 DI详解

目录 &#x1f334;什么是依赖注入 &#x1f384;依赖注入的三种方法 &#x1f6a9;属性注⼊(Field Injection) &#x1f6a9;Setter注入 &#x1f6a9;构造方法注入 &#x1f6a9;三种注⼊的优缺点 &#x1f333;Autowired存在的问题 &#x1f332;解决Autowired存在的…

Avnet RFSoC基于maltab得5G 毫米波 开发工具箱

使用 MATLAB 连接到 AMD Zynq™ RFSoC 评估板。使用 RF 附加卡执行 OTA 测试。使用 HDL Coder 部署算法 版本要求&#xff1a; 大于 2023b 需要以下支持包之一&#xff1a; 适用于 Xilinx 基于 Zynq 的无线电&#xff08;R2023b 及更早版本&#xff09;的通信工具箱支持包适…

neo4j-解决导入数据后出现:Database ‘xxxx‘ is unavailable. Run :sysinfo for more info.

目录 问题描述 解决方法 重新导入 问题描述 最近在linux上部署了neo4j&#xff0c;参照之前写的博客:neo4j-数据的导出和导入_neo4j数据导入导出-CSDN博客 进行了数据导出、导入操作。但是在进行导入后&#xff0c;重新登录网页版neo4j&#xff0c;发现对应的数据库状态变…

Mac(m1)本地部署deepseek-R1模型

1. 下载安装ollama 直接下载软件&#xff0c;下载完成之后&#xff0c;安装即可&#xff0c;安装完成之后&#xff0c;命令行中可出现ollama命令 2. 在ollama官网查看需要下载的模型下载命令 1. 在官网查看deepseek对应的模型 2. 选择使用电脑配置的模型 3. copy 对应模型的安…

【分布式理论9】分布式协同:分布式系统进程互斥与互斥算法

文章目录 一、互斥问题及分布式系统的特性二、分布式互斥算法1. 集中互斥算法调用流程优缺点 2. 基于许可的互斥算法&#xff08;Lamport 算法&#xff09;调用流程优缺点 3. 令牌环互斥算法调用流程优缺点 三、三种算法对比 在分布式系统中&#xff0c;多个应用服务可能会同时…

第一财经对话东土科技 | 探索工业科技新边界

当前以ChatGPT、Sora等为代表的生成式人工智能快速发展&#xff0c;越来越多面向垂直场景的行业大模型涌现出来&#xff0c;并成为推动制造业智能化改造与数字化转型、加快推进新型工业化&#xff0c;进而培育发展新质生产力的新引擎。 在垂类场景的应用落地&#xff0c;是AI发…

深入理解Java对接DeepSeek

其实&#xff0c;整个对接过程很简单&#xff0c;就四步&#xff0c;获取key&#xff0c;找到接口文档&#xff0c;接口测试&#xff0c;代码对接。 1.获取 KEY https://platform.deepseek.com/transactions 直接付款就是了&#xff08;现在官网暂停充值2025年2月7日&#xf…

线段平移 实战笔记

目录 pingyi2.py pingyi2.py import numpy as np import cv2# 画线段的函数 def draw_line(img, p1, p2, color, thickness=2):cv2.line(img, tuple(p1), tuple(p2), color, thickness)# 创建图像并初始化 def create_image():# 创建一个黑色背景图像img = np.zeros((500, 50…

WinForm 防破解、反编译设计文档

一、引言 1.1 文档目的 本设计文档旨在阐述 WinForm 应用程序防破解、反编译的设计方案&#xff0c;为开发团队提供详细的技术指导&#xff0c;确保软件的知识产权和商业利益得到有效保护。 1.2 背景 随着软件行业的发展&#xff0c;软件破解和反编译现象日益严重。WinForm…

DeepSeek应用——与word的配套使用

目录 一、效果展示 二、配置方法 三、使用方法 四、注意事项 1、永久化使用 2、宏被禁用 3、office的生成失败 记录自己学习应用DeepSeek的过程...... 这个是与WPS配套使用的过程&#xff0c;office的与这个类似&#xff1a; 一、效果展示 二、配置方法 1、在最上方的…

利用邮件合并将Excel的信息转为Word(单个测试用例转Word)

利用邮件合并将Excel的信息转为Word 效果一览效果前效果后 场景及问题解决方案 一、准备工作准备Excel数据源准备Word模板 二、邮件合并操作步骤连接Excel数据源插入合并域预览并生成合并文档 效果一览 效果前 效果后 场景及问题 在执行项目时的验收阶段&#xff0c;对于测试…

OpenCV 相机标定流程指南

OpenCV 相机标定流程指南 前置准备标定流程结果输出与验证建议源代码 OpenCV 相机标定流程指南 https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html https://learnopencv.com/camera-calibration-using-opencv/ 前置准备 制作标定板&#xff1a;生成高精度棋…

网络在线考试|基于vue的网络在线考试系统的设计与实现(源码+数据库+文档)

网络在线考试系统 目录 基于SSM&#xff0b;vue的网络在线考试系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1功能页面实现 2系统功能模块 3管理员功能模块 4学生功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八…

DEEPSEEK与GPT等AI技术在机床数据采集与数字化转型中的应用与影响

随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;深度学习、自然语言处理等先进技术开始广泛应用于各行各业。在制造业尤其是机床行业&#xff0c;AI技术的融合带来了巨大的变革&#xff0c;尤其在机床数据采集与机床数字化方面的应用。本文将探讨DEEPSEEK、…

【文本处理】如何在批量WORD和txt文本提取手机号码,固话号码,提取邮箱,删除中文,删除英文,提取车牌号等等一些文本提取固定格式的操作,基于WPF的解决方案

企业的应用场景 数据清洗&#xff1a;在进行数据导入或分析之前&#xff0c;往往需要对大量文本数据进行预处理&#xff0c;比如去除文本中的无关字符&#xff08;中文、英文&#xff09;&#xff0c;只保留需要的联系信息&#xff08;手机号码、固话号码、邮箱&#xff09;。…

17vue3实战-----使用配置文件生成简易页面

17vue3实战-----使用配置文件生成简易页面 1.写在前面2.背景3.实现3.1界面效果3.2新建config配置文件3.3封装组件3.4使用组件 1.写在前面 后台管理系统的开发很简单。无论是用户模块、部门模块、角色模块还是其它模块,界面和业务逻辑都相对比较简单&#xff0c;我会省略这些模…