当前位置: 首页 > news >正文

dict电子词典

1.服务器端

#include <myhead.h>
#include <asm-generic/socket.h>#define PORT 8888
#define IP "192.168.109.48"
#define BUFFER_SIZE 1024
#define DICT_FILE "dict.txt"// 处理子进程退出,回收子进程
void handle_sigchld(int sig) {while (waitpid(-1, NULL, WNOHANG) > 0);
}// 初始化数据库
int init_database(sqlite3 *db) {char *errmsg = NULL;char sql[BUFFER_SIZE];// 创建用户表strcpy(sql, "CREATE TABLE IF NOT EXISTS users (""id INTEGER PRIMARY KEY AUTOINCREMENT,""username TEXT UNIQUE NOT NULL,""password TEXT NOT NULL);");if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {fprintf(stderr, "创建用户表失败: %s\n", errmsg);sqlite3_free(errmsg);return -1;}// 创建历史记录表strcpy(sql, "CREATE TABLE IF NOT EXISTS history (""id INTEGER PRIMARY KEY AUTOINCREMENT,""username TEXT NOT NULL,""word TEXT NOT NULL,""time TEXT NOT NULL);");if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {fprintf(stderr, "创建历史记录表失败: %s\n", errmsg);sqlite3_free(errmsg);return -1;}return 0;
}// 注册用户
int register_user(sqlite3 *db, const char *username, const char *password) {char sql[BUFFER_SIZE];char *errmsg = NULL;sqlite3_stmt *stmt;// 检查用户是否已存在snprintf(sql, sizeof(sql), "SELECT username FROM users WHERE username = '%s'", username);if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {fprintf(stderr, "准备查询失败: %s\n", sqlite3_errmsg(db));return -1;}if (sqlite3_step(stmt) == SQLITE_ROW) {// 用户已存在sqlite3_finalize(stmt);return 1;}sqlite3_finalize(stmt);// 插入新用户snprintf(sql, sizeof(sql), "INSERT INTO users (username, password) VALUES ('%s', '%s')",username, password);if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {fprintf(stderr, "插入用户失败: %s\n", errmsg);sqlite3_free(errmsg);return -1;}return 0;
}// 用户登录验证
int login_user(sqlite3 *db, const char *username, const char *password) {char sql[BUFFER_SIZE];sqlite3_stmt *stmt;int result = 0;snprintf(sql, sizeof(sql), "SELECT password FROM users WHERE username = '%s'", username);if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {fprintf(stderr, "准备查询失败: %s\n", sqlite3_errmsg(db));return -1;}if (sqlite3_step(stmt) == SQLITE_ROW) {const char *db_password = (const char *)sqlite3_column_text(stmt, 0);if (strcmp(db_password, password) == 0) {result = 1; // 登录成功}}sqlite3_finalize(stmt);return result;
}// 查询单词
char *query_word(const char *word) {FILE *file = fopen(DICT_FILE, "r");if (!file) {perror("打开词典文件失败");return NULL;}static char definition[BUFFER_SIZE * 3];char line[BUFFER_SIZE * 3];char temp_word[BUFFER_SIZE];definition[0] = '\0';while (fgets(line, sizeof(line), file)) {// 提取每行的单词部分进行比较if (sscanf(line, "%s", temp_word) == 1 && strcmp(temp_word, word) == 0) {strcpy(definition, line + strlen(temp_word) + 1);fclose(file);return definition;}}fclose(file);return NULL;
}// 记录查询历史
int record_history(sqlite3 *db, const char *username, const char *word) {char sql[BUFFER_SIZE];char *errmsg = NULL;time_t now;struct tm *tm_info;char time_str[64];// 获取当前时间time(&now);tm_info = localtime(&now);strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_info);// 插入历史记录snprintf(sql, sizeof(sql), "INSERT INTO history (username, word, time) VALUES ('%s', '%s', '%s')",username, word, time_str);if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK) {fprintf(stderr, "记录历史失败: %s\n", errmsg);sqlite3_free(errmsg);return -1;}return 0;
}// 查询历史记录
int query_history(sqlite3 *db, const char *username, char *history_str) {char sql[BUFFER_SIZE];sqlite3_stmt *stmt;int count = 0;history_str[0] = '\0';snprintf(sql, sizeof(sql), "SELECT word, time FROM history WHERE username = '%s' ORDER BY time DESC LIMIT 10",username);if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {fprintf(stderr, "准备查询历史失败: %s\n", sqlite3_errmsg(db));return -1;}while (sqlite3_step(stmt) == SQLITE_ROW) {const char *word = (const char *)sqlite3_column_text(stmt, 0);const char *time = (const char *)sqlite3_column_text(stmt, 1);if (count > 0) {strcat(history_str, "\n");}snprintf(history_str + strlen(history_str), BUFFER_SIZE - strlen(history_str),"%s - %s", word, time);count++;}sqlite3_finalize(stmt);return count;
}// 处理客户端请求
void handle_client(int client_socket, sqlite3 *db) {char buffer[BUFFER_SIZE];char username[BUFFER_SIZE], password[BUFFER_SIZE], word[BUFFER_SIZE];int n;int logged_in = 0;char current_user[BUFFER_SIZE] = "";while (1) {// 清空缓冲区memset(buffer, 0, BUFFER_SIZE);// 接收客户端数据n = recv(client_socket, buffer, BUFFER_SIZE - 1, 0);if (n <= 0) {if (n < 0) perror("接收数据失败");break;}// 未登录状态:处理注册和登录if (!logged_in) {if (strncmp(buffer, "register:", 9) == 0) {// 处理注册sscanf(buffer + 9, "%s %s", username, password);int ret = register_user(db, username, password);if (ret == 0) {send(client_socket, "注册成功", strlen("注册成功"), 0);} else if (ret == 1) {send(client_socket, "用户名已存在", strlen("用户名已存在"), 0);} else {send(client_socket, "注册失败", strlen("注册失败"), 0);}} else if (strncmp(buffer, "login:", 6) == 0) {// 处理登录sscanf(buffer + 6, "%s %s", username, password);int ret = login_user(db, username, password);if (ret == 1) {logged_in = 1;strcpy(current_user, username);send(client_socket, "登录成功", strlen("登录成功"), 0);} else if (ret == 0) {send(client_socket, "用户名或密码错误", strlen("用户名或密码错误"), 0);} else {send(client_socket, "登录失败", strlen("登录失败"), 0);}}else if (strncmp(buffer, "quit", 4) == 0) {// 退出send(client_socket, "再见", strlen("再见"), 0);break;}else {send(client_socket, "请先注册或登录", strlen("请先注册或登录"), 0);}} // 已登录状态:处理查询和历史记录else {if (strncmp(buffer, "query:", 6) == 0) {// 处理单词查询sscanf(buffer + 6, "%s", word);char *definition = query_word(word);if (definition) {// 记录查询历史record_history(db, current_user, word);send(client_socket, definition, strlen(definition), 0);} else {send(client_socket, "not found", strlen("not found"), 0);}} else if (strncmp(buffer, "history", 7) == 0) {// 处理历史记录查询char history_str[BUFFER_SIZE * 10] = "";int count = query_history(db, current_user, history_str);if (count > 0) {send(client_socket, history_str, strlen(history_str), 0);} else {send(client_socket, "没有查询历史记录", strlen("没有查询历史记录"), 0);}}else if (strncmp(buffer, "quit", 4) == 0) {// 退出send(client_socket, "再见", strlen("再见"), 0);break;}else {send(client_socket, "无效命令", strlen("无效命令"), 0);}}}close(client_socket);printf("客户端连接关闭\n");
}int main(int argc,const char *argv[]) 
{int server_fd, new_socket;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);sqlite3 *db;char *errmsg = NULL;// 注册信号处理函数,处理子进程退出signal(SIGCHLD, handle_sigchld);// 打开SQLite数据库if (sqlite3_open("dictionary.db", &db) != SQLITE_OK) {fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));return 1;}// 初始化数据库表if (init_database(db) != 0) {sqlite3_close(db);return 1;}// 创建socket文件描述符if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");sqlite3_close(db);exit(EXIT_FAILURE);}// 设置socket选项,允许重用端口和地址if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt");sqlite3_close(db);exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = inet_addr(IP);address.sin_port = htons(PORT);// 绑定socket到指定IP和端口if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");sqlite3_close(db);exit(EXIT_FAILURE);}// 监听连接请求if (listen(server_fd, 3) < 0) {perror("listen");sqlite3_close(db);exit(EXIT_FAILURE);}printf("服务器启动,监听 %s:%d...\n", IP, PORT);// 接受并处理客户端连接while (1) {if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");continue;}printf("新客户端连接: %s:%d\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port));// 创建子进程处理客户端请求pid_t pid = fork();if (pid < 0) {perror("fork failed");close(new_socket);continue;}if (pid == 0) {// 子进程:处理客户端请求close(server_fd); // 子进程不需要监听sockethandle_client(new_socket, db);sqlite3_close(db);exit(0);} else {// 父进程:继续接受新连接close(new_socket); // 父进程不需要客户端socket}}sqlite3_close(db);return 0;
}

2.客户端

#include <myhead.h>#define PORT 8888
#define IP "192.168.109.48"
#define BUFFER_SIZE 1024int main() {int sock = 0;struct sockaddr_in serv_addr;char buffer[BUFFER_SIZE];int choice;char username[BUFFER_SIZE], password[BUFFER_SIZE], word[BUFFER_SIZE];int logged_in = 0;// 创建socketif ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {printf("\nSocket创建失败\n");return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);// 转换IP地址if (inet_pton(AF_INET, IP, &serv_addr.sin_addr) <= 0) {printf("\n无效的地址/地址不可达\n");return -1;}// 连接服务器if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {printf("\n连接失败\n");return -1;}printf("成功连接到服务器 %s:%d\n", IP, PORT);// 未登录状态:注册或登录while (!logged_in) {printf("\n请选择操作:\n");printf("1. 注册\n");printf("2. 登录\n");printf("3. 退出\n");printf("请输入选择: ");scanf("%d", &choice);getchar(); // 消耗换行符switch (choice) {case 1:// 注册printf("请输入用户名: ");fgets(username, BUFFER_SIZE, stdin);username[strcspn(username, "\n")] = 0; // 移除换行符printf("请输入密码: ");fgets(password, BUFFER_SIZE, stdin);password[strcspn(password, "\n")] = 0;// 发送注册请求snprintf(buffer, BUFFER_SIZE, "register:%s %s", username, password);send(sock, buffer, strlen(buffer), 0);// 接收服务器响应memset(buffer, 0, BUFFER_SIZE);read(sock, buffer, BUFFER_SIZE);printf("服务器响应: %s\n", buffer);break;case 2:// 登录printf("请输入用户名: ");fgets(username, BUFFER_SIZE, stdin);username[strcspn(username, "\n")] = 0;printf("请输入密码: ");fgets(password, BUFFER_SIZE, stdin);password[strcspn(password, "\n")] = 0;// 发送登录请求snprintf(buffer, BUFFER_SIZE, "login:%s %s", username, password);send(sock, buffer, strlen(buffer), 0);// 接收服务器响应memset(buffer, 0, BUFFER_SIZE);read(sock, buffer, BUFFER_SIZE);printf("服务器响应: %s\n", buffer);if (strcmp(buffer, "登录成功") == 0) {logged_in = 1;}break;case 3:// 退出send(sock, "quit", strlen("quit"), 0);memset(buffer, 0, BUFFER_SIZE);read(sock, buffer, BUFFER_SIZE);printf("服务器响应: %s\n", buffer);close(sock);return 0;default:printf("无效的选择,请重试\n");}}// 已登录状态:查询单词或历史记录while (logged_in) {printf("\n请选择操作:\n");printf("1. 查询单词\n");printf("2. 查看历史记录\n");printf("3. 退出\n");printf("请输入选择: ");scanf("%d", &choice);getchar(); // 消耗换行符switch (choice) {case 1:// 查询单词printf("请输入要查询的单词: ");fgets(word, BUFFER_SIZE, stdin);word[strcspn(word, "\n")] = 0;// 发送查询请求snprintf(buffer, BUFFER_SIZE, "query:%s", word);send(sock, buffer, strlen(buffer), 0);// 接收查询结果memset(buffer, 0, BUFFER_SIZE);read(sock, buffer, BUFFER_SIZE);printf("查询结果: %s\n", buffer);break;case 2:// 查看历史记录send(sock, "history", strlen("history"), 0);// 接收历史记录memset(buffer, 0, BUFFER_SIZE);read(sock, buffer, BUFFER_SIZE);printf("查询历史记录:\n%s\n", buffer);break;case 3:// 退出send(sock, "quit", strlen("quit"), 0);memset(buffer, 0, BUFFER_SIZE);read(sock, buffer, BUFFER_SIZE);printf("服务器响应: %s\n", buffer);logged_in = 0;break;default:printf("无效的选择,请重试\n");}}close(sock);return 0;
}


文章转载自:

http://BxcIkj67.fmrrr.cn
http://7ARIcFFk.fmrrr.cn
http://2eMwEPii.fmrrr.cn
http://5U3JdFj6.fmrrr.cn
http://BJS0pXHs.fmrrr.cn
http://mRO6EVCx.fmrrr.cn
http://LIJHqRzi.fmrrr.cn
http://h5Nfhulq.fmrrr.cn
http://7CYIuM5U.fmrrr.cn
http://kPpwfPGb.fmrrr.cn
http://J9wUkgEU.fmrrr.cn
http://F8yEOONs.fmrrr.cn
http://batmfEWE.fmrrr.cn
http://YMGXlKD5.fmrrr.cn
http://3Bak8bSA.fmrrr.cn
http://gy39nlaQ.fmrrr.cn
http://LhtJy0z7.fmrrr.cn
http://gsGF2JlR.fmrrr.cn
http://jds30X1p.fmrrr.cn
http://Tn57nFgC.fmrrr.cn
http://u2SxalVI.fmrrr.cn
http://KA165XPe.fmrrr.cn
http://jCy8RLws.fmrrr.cn
http://AhflxZHW.fmrrr.cn
http://XwXBPct8.fmrrr.cn
http://sEYRqbgJ.fmrrr.cn
http://ddzLM6ni.fmrrr.cn
http://ScBkhC65.fmrrr.cn
http://FTowNUKv.fmrrr.cn
http://VwL29cxb.fmrrr.cn
http://www.dtcms.com/a/387898.html

相关文章:

  • pulsar Error receiving messages.Consumer already closed at
  • 计算机视觉(opencv)实战二十五——摄像头动态轮廓识别
  • 简单易懂的Kafka例子
  • 针对tomcat [/usr/lib64:/lib64:/lib:/usr/lib]上找不到基于APR的Apache Tomcat本机库的处理方法
  • 【js】js实现日期转大写:
  • 番茄时钟小程序版本更新记录(v1.0)
  • css消除图片下的白边
  • 我是如何在electron里安装shadcn ui框架的
  • 【图像理解进阶】如何对猫猫的图片进行细粒度分类?
  • JSCPC/GDCPC 2025 J.Puzzle Competition(解谜游戏)
  • SpringMVC 系列博客(三):进阶功能与 SSM 整合实战
  • 电商网站反爬虫机制详解及应对策略
  • 没了CDN与PCDN,网络会怎样?
  • C++中std::vector Vs std::deque VS std::list对比详解
  • RecyclerView实现流式布局
  • 【连载5】C# MVC 异常处理避坑指南:异步操作与静态资源错误解决方案
  • 当控制器无法上网时,如何利用windows笔记本与控制器共享网络?
  • 企业数字化视角下的项目管理软件市场全景分析(2025版)
  • Python异步编程:asyncio.create_task() 用法解析
  • java面试Day1 | redis缓存穿透、击穿、雪崩、持久化、双写一致性、数据过期策略、数据淘汰策略、分布式锁、redis集群
  • Jenkins运维之路(容器项目的优化)
  • 【精品资料鉴赏】363页智慧旅游大数据平台项目建设设计方案
  • 软考 系统架构设计师系列知识点之杂项集萃(149)
  • MyBatis 中注解操作与 XML 映射文件操作的对比
  • 复杂 PDF 文档如何高效解析?
  • 加密网络流量分类
  • leetcode算法题记录:
  • VS安装后通过vswhere.exe查询显示的 installationVersion数字怎么不是2022?
  • 光伏电站安全 “守护神”:QB800 绝缘监测平台,为清洁能源高效运行筑固防线
  • STC携手非小号 Talking Web3,海上ALPHA WEB3派对启航