电子词典:

  1. 登录注册功能,不能重复登录,重复注册

  2. 单词查询功能

  3. 历史记录功能,存储单词,意思,以及查询时间

  4. 基于TCP,支持多客户端连接

  5. 采用数据库保存用户信息与历史记录

  6. 将dict.txt的数据导入到数据库中保存。

服务器代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <fcntl.h>
#include <signal.h>
#include<sys/stat.h>
#include <sys/wait.h>
#define ERR_MSG(msg) do{\fprintf(stderr, "__%d__:", __LINE__);\perror(msg);\
}while(0)
#define PORT 8888
#define IP "192.168.0.177"
typedef void (*sighandler_t)(int);
typedef struct
{int type;char name[20];char data[256];
}MSG[30];
int n=0;
int fp;
int newfd;
sqlite3*db;
char *errmsg;
int rcv_cli_msg(int newfd, struct sockaddr_in cin);
int do_load();
int do_select(char *words);
void handler(int sig)
{while(waitpid(-1,NULL,WNOHANG)>0);
}
int main(int argc, const char *argv[])
{sighandler_t s=signal(SIGCHLD, handler);if(SIG_ERR==s){ERR_MSG("signal");return -1;}int sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd<0){ERR_MSG("socket");return -1;}int reuse=1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0){ERR_MSG("setsockopt");return -1;}printf("快速重用成功\n");struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(PORT);sin.sin_addr.s_addr=inet_addr(IP);if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin))<0){ERR_MSG("bind");return -1;}printf("bind success\n");if(listen(sfd,10)<0){ERR_MSG("listen");return -1;}printf("listen success\n");struct sockaddr_in cin;socklen_t addrlen=sizeof(cin);if(access("./dict.db",F_OK)<0){do_load();}else{if(unlink("./dict.db")==0){do_load();}}pid_t pid;MSG msg;while(1){newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);if(newfd<0){ERR_MSG("accept");return -1;}printf("[%s:%d] newfd=%d客户端已连接\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);pid = fork();if(0 == pid){close(sfd);rcv_cli_msg(newfd, cin);close(newfd);exit(0);}else if(pid > 0){close(newfd);}else{ERR_MSG("fork");return -1;}}close(sfd);return 0;
}
int do_load()
{sqlite3* db = NULL;if(sqlite3_open("./dict.db", &db) != SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_open: %s\n", __LINE__, sqlite3_errmsg(db));fprintf(stderr, "error_code:%d\n", sqlite3_errcode(db));return -1;}printf("sqlite3 open success\n");char sql[128]="create table if not exists dictionary(word char,interpret char);";char *errmsg=NULL;if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK){fprintf(stderr,"__%d__sqlite3_exec:%s\n",__LINE__,errmsg);return -1;}printf("创建成功\n");char word[50]="";char interpret[128]="";int fd=open("./dict.txt",O_RDONLY);if(fd<0){perror("open");return -1;}ssize_t res;while(1){bzero(word,sizeof(word));bzero(interpret,sizeof(interpret));int i=0;int j=0;while(1){if((res=read(fd,&word[i],1))<0){perror("read");return -1;}if(res==0){printf("加载完成\n");return 0;}if(word[i]==' '){break;}i++;}while(1){if(read(fd,&interpret[j],1)<0){perror("read");return -1;}if(interpret[j]=='\n'){break;}j++;}sprintf(sql,"insert into dictionary values(\"%s\",'%s')",word,interpret);if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)){fprintf(stderr,"__%d__sqlite3_exec:%s\n",__LINE__,errmsg);return -1;}}close(fd);
}
int rcv_cli_msg(int newfd, struct sockaddr_in cin)
{MSG msg;char buf[128] = "";ssize_t res=0;char data1[300];int flag;while(1){bzero(buf, sizeof(buf));bzero(data1,sizeof(data1));res=recv(newfd, buf, sizeof(buf), 0);if(res<0){ERR_MSG("recv");return -1;}else if(0 == res){fprintf(stderr, "[%s:%d] newfd=%d 客户端关闭\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);break;}printf("[%s:%d] newfd=%d : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, buf);strcpy(data1,buf);if(data1[0]=='1'){char *p=(buf+1);strcpy(msg[n].data,p);n++;if(n>29){printf("注册人数已达上限\n");return -1;}printf("注册成功\n");}else if(data1[0]=='2'){for(int i=0;i<10;i++){char *q=(buf+1);if(strcmp(msg[i].data,q)==0){flag=1;printf("登录成功\n");break;}else{flag=0;}}send(newfd,&flag,sizeof(flag),0);}else if(data1[0]=='3'){char *p=(buf+1);int fp;char arr[128] ="search word failed";fp=do_select(p);if(fp==20){send(newfd,arr,sizeof(arr),0);}}}return 0;
}
int callback(void *arg,int columns,char **column_text,char **column_name)
{char buf[128] = "";int i=0;fp=0;if(fp==0){fp=1;}for(i=0;i<columns;i++){strcat(buf,*(column_text+i));}send(newfd,buf,sizeof(buf),0);
}
int do_select(char *words)
{char sql[128] = "";sprintf(sql,"select * from dictionary where word=\"%s\";",words);if((sqlite3_exec(db,sql,callback,NULL,&errmsg))!=SQLITE_OK){fprintf(stderr,"__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);return -1;}fp=0;printf("search word success\n");
}

客户端代码:

#include <stdio.h>
#include<sqlite3.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include <unistd.h>
#include <sqlite3.h>
#define ERR_MSG(msg) do{\fprintf(stderr, "__%d__:", __LINE__);\perror(msg);\
}while(0)
#define PORT 8888
#define IP "192.168.0.177"
#define R 1
#define L 2
#define Q 3
#define H 4
typedef struct
{int type;char name[20];char data[256];
}MSG;
typedef struct
{char history[128];
}HIS[128];
int do_register(int sfd,MSG *msg);
int do_signin(int sfd,MSG *msg);
int do_query(int sfd,MSG *msg,HIS *his);
int history(int sfd,HIS *his);
int m;
int main(int argc, const char *argv[])
{m=0;sqlite3* db=NULL;if(sqlite3_open("./user.db",&db)!=SQLITE_OK){fprintf(stderr,"__%d__ sqlite3_open:%s\n",__LINE__,sqlite3_errmsg(db));fprintf(stderr,"error_code:%d\n",sqlite3_errcode(db));return -1;}printf("sqlite3 open success\n");char sql[128]="create table if not exists user (name char,data char);";char *errmsg=NULL;if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK){fprintf(stderr, "__%d__ sqlite3_exec: %s\n", __LINE__, errmsg);return -1;}MSG msg;HIS his;int sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd<0){ERR_MSG("socket");return -1;}struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(PORT); sin.sin_addr.s_addr=inet_addr(IP);if(connect(sfd,(struct sockaddr*)&sin,sizeof(sin))<0){ERR_MSG("connect");return -1;}printf("success\n");int c=0;ssize_t res;
begin:while(1){printf("--------------------------\n");printf("----------1.注册----------\n");printf("----------2.登录----------\n");printf("----------3.退出----------\n");printf("--------------------------\n");printf("请输入:");scanf("%d",&c);getchar();switch(c){case 1:do_register(sfd,&msg);break;case 2:res=do_signin(sfd,&msg);if(1==res){printf("登录成功\n");goto next;}printf("登录失败\n");break;case 3:goto END;default:printf("输入错误,请重新输入\n");}}
next:while(1){printf("--------------------------\n");printf("--------1.查询单词--------\n");printf("--------2.历史记录--------\n");printf("--------3.注销用户--------\n");printf("--------------------------\n");printf("请输入:");scanf("%d",&c);getchar();switch(c){case 1:do_query(sfd,&msg,&his);break;case 2:history(sfd,&his);break;case 3:goto begin;default:printf("输入错误,请重新输入\n");}}
END:close(sfd);exit(0);return 0;
}
int do_register(int sfd,MSG *msg)
{char buf[300] = "";msg->type=R;printf("请输入注册用户名:");scanf("%s",msg->name);while(getchar()!=10);printf("请输入注册密码:");scanf("%s",msg->data);while(getchar()!=10);sprintf(buf,"%d%s%s",msg->type,msg->name,msg->data);send(sfd,buf,sizeof(buf),0);printf("注册成功\n");
}
int do_signin(int sfd,MSG *msg)
{int flag;char buf[300] = "";char name[20] = "";char data[256] = "";printf("请输入用户名:");scanf("%s",name);while(getchar() != 10);printf("请输入密码:");scanf("%s",data);while(getchar() != 10);sprintf(buf,"%d%s%s",L,name,data);send(sfd,buf,sizeof(buf),0);recv(sfd,&flag,sizeof(flag),0);return flag;
}
int do_query(int sfd,MSG *msg,HIS *his)
{char buf[300] = "";char select[128] = "";msg->type = Q;char word[128] = "";printf("请输入要查询的单词:");scanf("%s",word);sprintf(buf,"%d%s",msg->type,word);send(sfd,buf,sizeof(buf),0);recv(sfd,select,sizeof(select),0);strcpy(his[m]->history,select);m++;printf("%s\n",select);return 1;
}
int history(int sfd,HIS *his)
{for(int i=0;i<m;i++){printf("%s\n",his[i]->history);}return 1;
}

华清远见上海中心22071班 9.30作业相关推荐

  1. 华清远见上海中心22071班--8.30作业

    第一题. 第二题.

  2. 华清远见上海中心22071班 9.2作业

    1.用父子进程拷贝一张图片,其中子进程先拷贝后半部分,父进程后拷贝前半部分.要求用文件IO实现. 函数: #include <stdio.h> #include <fcntl.h&g ...

  3. 华清远见上海中心22071班--11.19作业

    题目:实现开发板点灯操作 程序要求: 1)分部实现注册字符设备驱动 2)自动创建设备节点 3)通过结构体对led灯地址进行映射 4)次设备号完成私有数据传参 5)在open函数中获取到次设备号,用私有 ...

  4. 华清远见上海中心22071班 9.7作业

    目录 1.创建两个线程 A.B,要求A线程读取文件中的数据,B线程将读取到的数据打印到终端上,类似shell命令cat. 2.编写一个程序,开启3个线程,这3个线程的ID分别为A.B.C,每个线程将自 ...

  5. 华清远见上海中心22071班 8.24作业

    1.单向链表按位置修改 void list_update_pos(linklist *L,int pos,datatype e) {if(NULL==L||list_empty(L)||pos< ...

  6. 华清远见上海中心22071班 9.21作业

    1.完成数据库的插入.删除.修改,插入选择全字段插入.删除.修改选择用id的方式 代码: #include <stdio.h> #include <sqlite3.h> #in ...

  7. 华清远见上海中心22071班 9.19作业

    目录 1.并发服务器 1)多进程并发服务器 2)多线程并发服务器 2.域套接字 1.流式域套接字(TCP) 1.1服务器 1.2客户端 2.报式套接字(UDP) 2.1服务器 2.2客户端 1.并发服 ...

  8. 华清远见上海中心22071班 8.25作业

    目录 1.用无头结点的循环链表实现约瑟夫环问题 头文件: 功能函数: 主函数: 终端输出: 2.顺序栈实现进制转换问题 头文件: 功能函数: 主函数: 终端输出: 1.用无头结点的循环链表实现约瑟夫环 ...

  9. 华清远见上海中心22071班--11.24作业

    题目:应用层采取ioctl命令控制,驱动代码用GPIO子系统,实现开发板6盏灯的循环亮灭 头文件程序: #ifndef __LED_H__ #define __LED_H__typedef enum{ ...

最新文章

  1. 使用VS2005进行代码覆盖率分析
  2. gdb 查看,执行汇编代码
  3. 自定义错误代码和提示信息
  4. 第四期直播分享预告-高薪offer指南
  5. [Oracle] Enable Row Movement
  6. sql两个列值以下划线拼接得到一个新的列_面试必备sql知识点——MySQL基础
  7. leetcode503. 下一个更大元素 II
  8. W​o​r​d​P​r​e​ss数据结构分析
  9. 腾讯通如何修改服务器,rtx如何设置服务器地址
  10. 用Ruby读取Excel文件
  11. 如何在Linux上录制你的终端操作
  12. 布朗大学计算机专业怎么样,Offer捷报 | 恭喜Z同学收获布朗大学计算机科学专业Offer!...
  13. mysql jdbc8.0驱动包下载_JDBC驱动jar包|JDBC驱动(mysql connector java)下载v8.0.11安装包 - 欧普软件下载...
  14. undo歌词中文音译_求sanna Nielsen 唱的undo 中文谐音歌词
  15. 死磕 Fragment 的生命周期
  16. K8S标签和污点容忍
  17. android studio怎么后退,Android Studio:上一个活动的后退按钮
  18. CTF-Crypto学习1(软件加壳、反汇编、Babe64、Rijndael密码算法)
  19. Java编程笔记6:接口
  20. 弄清楚这个三角关系,工作效率提高50%

热门文章

  1. 魂斗罗(CONTRA EVOLUTION):进化革命PC版
  2. 论文精读《Prototypical Networks for Few-shot Learning》
  3. 人工智能时代,普通的我们如何提升自己的核心竞争力
  4. qnx挂死恢复脚本简易写法
  5. 深度剖析不同企业类型私域运营的方法
  6. RFID基础知识习题
  7. Hero In Maze 简单版
  8. 学习java23种设计模式自我总结
  9. Java前后端分离验证码处理思路
  10. 第二章:IEEE2030.5官网相关资料介绍