在线英英词典
项目功能描述:
用户注册和登录验证:服务器端将用户信息和历史记录保存在数据库中,客户端填写用户名和密码,服务器端在数据库中查找、匹配、返回结果。
单词在线翻译:根据客户端输入的单词在字典文件中搜索,
历史记录查询:
项目分析:
项目流程:
定义数据库中表的结构;
定义消息结构体;
分析服务器和客户端流程;
编码实现。
第一步:
先在数据库中建立两个表:usr和record
usr表是用户账号信息表
record表是用户查询单词记录表
还有词典库:dict.txt
代码:
服务器:
dicts.h

/*===============================================
*   文件名称:dicts.h
*   创 建 者:
*   创建日期:2022年09月18日
*   描    述:
================================================*/#ifndef _DICTS_H_#define _DICTS_H_#define N 64#define R 1//user register#define L 2//user login#define Q 3//user query#define H 4//user history#define DATABASE "my.db"//定义通信双方的信息结构体typedef struct {int type;char name[N];char  data[512];}MSG;
//服务器函数声明
int do_client(int acceptfd,sqlite3 *db);
void  do_register(int acceptfd,MSG *msg,sqlite3 *db);
int do_login(int acceptfd,MSG *msg,sqlite3 *db);
int  do_query(int acceptfd,MSG *msg,sqlite3 *db);
int do_history(int acceptfd,MSG *msg,sqlite3 *db);
int history_callback(void *arg,int f_num,char **f_value,char **f_name);
int do_searchword(int acceptfd,MSG *msg,char word[]);
int get_date(char *date);
#endif

dicts.c

/*===============================================
*   文件名称:dicts.c
*   创 建 者:
*   创建日期:2022年09月18日
*   描    述:
================================================*/
#include <stdio.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 <time.h>
#include <sqlite3.h>
#include <signal.h>
#include <strings.h>
#include "dicts.h"//服务器函数定义int do_client(int acceptfd,sqlite3 *db)
{MSG msg;while(recv(acceptfd,&msg,sizeof(msg),0)>0){printf("type:%d\n",msg.type);switch(msg.type){case R:do_register(acceptfd,&msg,db);break;case L:do_login(acceptfd,&msg,db);break;case Q:do_query(acceptfd,&msg,db);break;case H:do_history(acceptfd,&msg,db);break;default:printf("Invalid data msg\n");}}printf("client exit.\n");close (acceptfd);exit(0);return 0;
}void do_register(int acceptfd,MSG *msg,sqlite3*db)
{char *errmsg;char sql[1024]={0};//char **resultp;//int nrow,ncolumn;memset (sql,0,sizeof(sql));sprintf(sql,"insert into usr values('%s','%s')",msg->name,msg->data);printf("%s\n",sql);if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK){printf("%s\n",errmsg);strcpy(msg->data,"usr name already exist.");}else{printf("client register ok!\n");strcpy(msg->data,"OK!");}if(send(acceptfd,msg,sizeof(MSG),0)<0){perror("send");return ;}return ;}
int  do_login(int acceptfd,MSG *msg,sqlite3 *db)
{char sql[1024]={0};char *errmsg;int nrow;int ncloumn;char**resultp;memset(sql,0,sizeof(sql));sprintf(sql,"select * from usr where name=('%s')and passwd=('%s');",msg->name,msg->data);printf("%s\n",sql);if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncloumn,&errmsg)!=SQLITE_OK)//执行SQL指令{printf("%s\n",errmsg);return -1;}else{printf("get_table ok!\n");}//查询成功,数据库中存在此用户if(nrow==1){memset(msg->data,0,strlen(msg->data));strcpy(msg->data,"OK");send(acceptfd,msg,sizeof(MSG),0);}return 1;if(nrow==0){memset(msg->data,0,strlen(msg->data));strcpy(msg->data,"usr/passwd wrong.");send(acceptfd,msg,sizeof(MSG),0);}return 0;}int do_searchword(int acceptfd,MSG *msg,char word [])
{FILE *fp;int len=0;char temp[512]={0};int result;char *p;if((fp=fopen("dict.txt","r"))==NULL){perror("fopen");strcpy(msg->data,"fail open dict.txt");send(acceptfd,msg,sizeof(MSG),0);return -1;}//打印chu客户端要查询的单词len=strlen(word);printf("%s,len=%d\n",word,len);//读文件,来查询单词while(fgets(temp,512,fp)!=NULL){result=strncmp(temp,word,len);if(result<0){continue;}if(result>0||((result==0)&&(temp[len]!=' '))){break;}//表示找到了查询的单词p=temp+len;while(*p==' '){p++;}//找到了注释,跳跃过所有的空格strcpy(msg->data,p);printf("found word:%s\n",msg->data);//注释拷贝完毕之后应该关闭文件fclose(fp);return 1;}fclose(fp);return 0;
}
int get_date(char *date)
{time_t t;struct tm *tp;time (&t);//将秒数转换为当地的时间tp=localtime(&t);sprintf(date,"%d年%d月%d日 %d时%d分%d秒",tp->tm_year+1900,tp->tm_mon+1,tp->tm_mday,tp->tm_hour,tp->tm_min,tp->tm_sec);printf("get date:%s\n",date);return 0;
}
int  do_query(int acceptfd,MSG *msg,sqlite3 *db)
{char word[64]={0};int found=0;char date[128]={0};char *errmsg;char sql[512]={0};//拿出msg结构体中要查询的单词strcpy(word,msg->data);found=do_searchword(acceptfd,msg,word);printf("已查到一个单词:%s\n",word);//将用户名,时间,单词,插入到历史记录中去if(found==1){get_date(date);sprintf(sql,"insert into record values('%s','%s','%s')",msg->name,date,word);printf("%s\n",sql);if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK){printf("%s\n",errmsg);return -1;}else{printf("insert record done!\n");}}else{//表示没有找到strcpy(msg->data,"no fund!");}//将查询的结果,发送给客户端send(acceptfd,msg,sizeof(MSG),0);return 0;
}
//得到查询结果,并且需要将历史记录发送给客户端
int history_callback(void *arg,int f_num,char **f_value,char** f_name)
{//   printf("history_callback");//record name date wordint acceptfd;MSG msg;acceptfd=*((int *)arg);sprintf(msg.data,"%s,%s",f_value[1],f_value[2]);send(acceptfd,&msg,sizeof(MSG),0);return 0;
}
int  do_history(int acceptfd,MSG *msg,sqlite3 *db)
{char sql[512]={0};char *errmsg;sprintf(sql,"select* from record where name='%s';",msg->name);//查询数据库if(sqlite3_exec(db,sql,history_callback,(void*)&acceptfd,&errmsg)!=SQLITE_OK){printf("%s\n",errmsg);}else{printf("query record done!\n");}//所有的记录查询发送完毕之后,给客户端发出一个结束信息msg->data[0]='\0';send(acceptfd,msg,sizeof(MSG),0);return 0;
}

server.c

/*=================================================*   文件名称:server.c*   创 建 者:     *   创建日期:2022年09月11日*   描    述:================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sqlite3.h>
#include <signal.h>
#include <strings.h>
#include "dicts.h"int main(int argc, const char *argv[])
{    int sockfd;int n;MSG msg;sqlite3 *db;int acceptfd;pid_t pid;struct sockaddr_in saddr;//结构体定义if(argc!=3){printf("Usage: %s serverip port .\n",argv[0]);return -1;}//打开数据库if(sqlite3_open(DATABASE,&db)!=SQLITE_OK){printf("%s\n",sqlite3_errmsg(db));return -1;}else{printf("open DATABASE success.\n");}if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)//创建套接字{perror("socket");return -1;}printf("socket success!\n");int on=1;if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0){perror("setsockopt");return -1;}bzero(&saddr,sizeof(saddr));//结构体清零saddr.sin_family=AF_INET;//设置地址类型AF_INETsaddr.sin_addr.s_addr=inet_addr(argv[1]);//网络地址saddr.sin_port=htons(atoi(argv[2]));//端口号//saddr.sin_addr.s_addr=inet_addr("92.168.31.122");//saddr.sin_port=htons(9999);if(bind(sockfd,(struct sockaddr *)&saddr,sizeof(saddr))<0)//将地址和端口号与套接字绑定{perror("bind");return -1;}printf("bind success!\n");//监听将套接字设置为监听模式if(listen (sockfd,5)==-1){perror("listen");return -1;}printf("listen success!\n");signal(SIGCHLD,SIG_IGN);//处理僵尸进程while(1){if((acceptfd=accept(sockfd,NULL,NULL))<0)//接受连接请求,从此函数中返回后就可以开始通信了{perror("accept");return -1;}printf("accept success!\n");if((pid=fork())<0){perror("fork");return -1;}else if(pid==0)//子进程{//处理客户端具体的消息close(sockfd);do_client(acceptfd,db);}else//父进程,用来接收客户端的请求{close(acceptfd);}}return 0;
}

客户端:
dict.h

/*===============================================
*   文件名称:dict.h
*   创 建 者:
*   创建日期:2022年09月18日
*   描    述:
================================================*/
#ifndef _DICT_H_
#define _DICT_H_#define N 64#define R 1//user register#define L 2//user login#define Q 3//user query#define H 4//user history#define DATABASE "my.db"//定义通信双方的信息结构体typedef struct {int type;char name[N];char  data[512];}MSG;//函数声明
//客户端函数声明
int do_register(int sockfd,MSG *msg);
int  do_login(int sockfd,MSG *msg);int  do_query(int sockfd,MSG *msg);int  do_history(int sockfd,MSG *msg);#endif

dict.c

/*===============================================*   文件名称:dict.c*   创 建 者:     *   创建日期:2022年09月18日*   描    述:================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include "dict.h"
//函数的定义:
//客户端函数的定义
int do_register(int sockfd,MSG *msg)
{msg->type=R;printf("input name:");scanf("%s",msg->name);getchar();printf("input passwd:");scanf("%s",msg->data);getchar();if(send(sockfd,msg,sizeof(MSG),0)<0){printf("fail to send.\n");return -1;}if(recv(sockfd,msg,sizeof(MSG),0)<0){printf("fali to recv.\n");return -1;}//success or usr alread exist.printf("%s\n",msg->data);return 0;
}int  do_login(int sockfd,MSG *msg)
{msg->type=L;printf("input name:");scanf("%s",msg->name);getchar();printf("input passwd:");scanf("%s",msg->data);getchar();if(send(sockfd,msg,sizeof(MSG),0)<0){printf("fail to send.\n");return -1;}if(recv(sockfd,msg,sizeof(MSG),0)<0){printf("fail to recv.\n");return -1;}if(strncmp(msg->data,"OK",3)==0){printf("login ok\n");return 1;}elseprintf("%s\n",msg->data);return 0;
}
int  do_query(int sockfd,MSG *msg)
{msg->type=Q;puts(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");while (1){printf("input word:");scanf("%s",msg->data);getchar();if(strncmp(msg->data,"#",1)==0){break;}//将要查询的单词发送给服务器if(send(sockfd,msg,sizeof(MSG),0)<0){printf("fail to send.\n");return -1;}//等待接受服务器,传递回来的单词注释信息if(recv(sockfd,msg,sizeof(MSG),0)<0){printf("fail to recv.\n");return -1;}printf("%s\n",msg->data);//打印服务器查询的数据}return 0;
}
int  do_history(int sockfd,MSG *msg)
{msg->type=H;send(sockfd,msg,sizeof(MSG),0);//·接受服务器传递回来的历史信息while(1){recv(sockfd,msg,sizeof(MSG),0);if(msg->data[0]=='\0')break;//输出历史记录信息printf("%s\n",msg->data);}return 0;
}

client.c

/*===============================================*   文件名称:client.c*   创 建 者:     *   创建日期:2022年09月11日*   描    述:================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include "dict.h"int main(int argc, const  char *argv[])
{    int sockfd;int n;MSG msg;struct sockaddr_in saddr;if(argc!=3){printf("Usage: %s serverip port .\n",argv[0]);return -1;}if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){perror("socket");return -1;}printf("socket success\n");bzero(&saddr,sizeof(saddr));saddr.sin_family=AF_INET;saddr.sin_addr.s_addr=inet_addr(argv[1]);saddr.sin_port=htons(atoi(argv[2]));// saddr.sin_addr.s_addr=inet_addr("192.168.31.122");// saddr.sin_port=htons(9999);if(connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr))<0){perror("connect");return -1;}printf("connect success!");while(1){printf("*********************************************\n");printf("*         1:register   2:login   3:quit     *\n");printf("*********************************************\n");printf("please  choose :\n");scanf("%d",&n);getchar();//去掉垃圾字符switch (n){case 1:do_register(sockfd,&msg);//注册break;case 2:if(do_login(sockfd,&msg)==1);//登录{goto next;}break;case 3:close(sockfd);//关闭套截字exit(0);break;default:printf("Invalid data cmd\n");}}
next://第二页面while(1){printf("***********************************\n");printf("*  1:query_word 2:history   3:quit*\n");printf("***********************************\n");printf("please choose:");scanf("%d",&n);getchar();//吃掉输入时的垃圾字符switch (n){ case 1:do_query(sockfd,&msg);//查询单词break;case 2://历史记录do_history(sockfd,&msg);break;case 3:close(sockfd);//关闭套接字exit(0);break;default: printf("Invalid data cmd.\n");}}return 0;
}

效果演示:
连接一个客户端


连接多个客户端:

网络编程-在线英英词典项目相关推荐

  1. 基于数据库及TCP网络编程实现的电子词典

    目录 一.前言 二.项目介绍 三.功能实现 3.1. 用户注册 3.1.1 功能演示 3.1.2 功能函数实现 3.2. 用户登录 3.2.1 功能演示 3.2.2 功能函数实现 3.3. 查询单词 ...

  2. Linux网络编程——在线词典项目

    目录 一.要求 二.框架 三.各部分的实现 客户端 注册 登录 查询 历史查询 服务器 解析客户端命令 注册 登录 单词查询 时间获取 查询单词成功向数据库插入时间等信息 历史查询 四.项目源码 客户 ...

  3. 基于linux的在线英汉词典(带源码)

    源码下载: 基于Linux的在线英汉词典-网络基础文档类资源-CSDN文库https://download.csdn.net/download/qq_63626307/86744311?spm=100 ...

  4. 基于Linux平台的TCP通信并发服务器---在线英语词典项目

    文章目录 前言 一.什么是并发服务器 二.服务器的实现 三.客户端的实现 四.代码测试结果 五.代码测试注意 总结 前言 本文是我在IO进线程.网络编程学习阶段的练习项目.项目基于linux平台,利用 ...

  5. java 缘起_缘起 网络编程

    我为什么要学习Java网络编程,在实际的项目开发中,尤其是移动电信领域.很不辛或者是很辛运来到这个行业.之所以这样说是因为我之前做的项目一般的都是CRUD的基本操作,虽然说现在的Java企业架构一般都 ...

  6. Linux网络编程之六 --在线英英字典的实现

    综合项目:在线英英字典 服务器端 head.h: ​ server.c do_client.c Makefile 客户端 head.h client.c Makefile 关注微信公众号获取更多资讯

  7. 【小型JavaFx项目】英汉词典

    英汉词典 简介 知识点简介 效果图 源代码 Word.java DictionaryFunction.java DictionaryFrame.java 简介 花了1个多小时帮数媒的同学用以前的项目改 ...

  8. python电子英汉词典显示_如何使用python为Linux打造一款命令行下的在线英汉词典...

    项目说明 : 在linux终端下有时候遇到一个想查询的英语单词 , 但是不想打开浏览器去谷歌或者百度去搜索 , 因此就写了这个基于爬虫的单词翻译工具 , 实现原理很简单 , 基本开发已经完成 ,总共有 ...

  9. c语言电子英汉词典编程报告,电子英汉词典的编程C语言报告.doc

    课程设计(论文) 课 题: 电子英汉词典的编程 学 院: 专 业: 学生姓名: 学 号: 指导老师 : 目录 *内容摘要-----------.---..-------------..3 *关键词-- ...

  10. 通过游戏编程学Python(6)— 英汉词典、背单词

    通过游戏编程学Python 通过游戏编程学Python(番外篇)- 乱序成语.猜单词 通过游戏编程学Python(5)- 猜成语(下) 通过游戏编程学Python(4)- 猜成语(上) 文章目录 通过 ...

最新文章

  1. 高级软件工程第二次作业
  2. leetcode算法题--叶值的最小代价生成树
  3. datatables设置解析
  4. Spring中的ModelAndView
  5. jquery find 找到frame select_简述jQuery
  6. java串口发送16进制数据_MFC串口通信发送16进制数据的方法
  7. 计算机基础教育学,计算机基础教育教学改革与创新
  8. 基于Matlab的跨孔CT胖射线追踪算法(三)
  9. iOS之StatusBar详解
  10. 教你一键式下载iOS旧版APP(2021年有效)
  11. 快手视频以及评论获取
  12. 解决Win10无法安装运行SqlServer 2000
  13. 什么是物联网(IoT)?
  14. 全球爆发计算机勒索病毒
  15. ***【九度oj-1343】城际公路网
  16. Android客户端与PC服务器实现Socket通信
  17. 网易163邮箱配置-iOS、OS X邮箱客户端
  18. 拼多多新手商家开直通车一定要避免的雷区有哪些?
  19. 《计算机网络自顶向下方法》读书笔记(五):链路层和局域网
  20. 代码行为异常容错机制与自我调节

热门文章

  1. RS232通信以及dB9定义
  2. Java GUI实现图书管理系统
  3. 前端图片文字复制粘贴功能
  4. 强烈推荐-百度网盘不限速下载网站
  5. 01.视频播放器框架介绍
  6. Selenium +Python项目实践(注册流程)
  7. 你要的Chrome插件都在这里了
  8. 解析android手游lua脚本的加密与解密(番外篇之反编译的对抗)
  9. 子账号授权服务器,京东子账号装修权限之怎么授权使用详情页模板市场?
  10. python能当黑客吗_如何成为一名黑客?(转)