网络编程-在线英英词典项目
在线英英词典
项目功能描述:
用户注册和登录验证:服务器端将用户信息和历史记录保存在数据库中,客户端填写用户名和密码,服务器端在数据库中查找、匹配、返回结果。
单词在线翻译:根据客户端输入的单词在字典文件中搜索,
历史记录查询:
项目分析:
项目流程:
定义数据库中表的结构;
定义消息结构体;
分析服务器和客户端流程;
编码实现。
第一步:
先在数据库中建立两个表: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;
}
效果演示:
连接一个客户端
连接多个客户端:
网络编程-在线英英词典项目相关推荐
- 基于数据库及TCP网络编程实现的电子词典
目录 一.前言 二.项目介绍 三.功能实现 3.1. 用户注册 3.1.1 功能演示 3.1.2 功能函数实现 3.2. 用户登录 3.2.1 功能演示 3.2.2 功能函数实现 3.3. 查询单词 ...
- Linux网络编程——在线词典项目
目录 一.要求 二.框架 三.各部分的实现 客户端 注册 登录 查询 历史查询 服务器 解析客户端命令 注册 登录 单词查询 时间获取 查询单词成功向数据库插入时间等信息 历史查询 四.项目源码 客户 ...
- 基于linux的在线英汉词典(带源码)
源码下载: 基于Linux的在线英汉词典-网络基础文档类资源-CSDN文库https://download.csdn.net/download/qq_63626307/86744311?spm=100 ...
- 基于Linux平台的TCP通信并发服务器---在线英语词典项目
文章目录 前言 一.什么是并发服务器 二.服务器的实现 三.客户端的实现 四.代码测试结果 五.代码测试注意 总结 前言 本文是我在IO进线程.网络编程学习阶段的练习项目.项目基于linux平台,利用 ...
- java 缘起_缘起 网络编程
我为什么要学习Java网络编程,在实际的项目开发中,尤其是移动电信领域.很不辛或者是很辛运来到这个行业.之所以这样说是因为我之前做的项目一般的都是CRUD的基本操作,虽然说现在的Java企业架构一般都 ...
- Linux网络编程之六 --在线英英字典的实现
综合项目:在线英英字典 服务器端 head.h: server.c do_client.c Makefile 客户端 head.h client.c Makefile 关注微信公众号获取更多资讯
- 【小型JavaFx项目】英汉词典
英汉词典 简介 知识点简介 效果图 源代码 Word.java DictionaryFunction.java DictionaryFrame.java 简介 花了1个多小时帮数媒的同学用以前的项目改 ...
- python电子英汉词典显示_如何使用python为Linux打造一款命令行下的在线英汉词典...
项目说明 : 在linux终端下有时候遇到一个想查询的英语单词 , 但是不想打开浏览器去谷歌或者百度去搜索 , 因此就写了这个基于爬虫的单词翻译工具 , 实现原理很简单 , 基本开发已经完成 ,总共有 ...
- c语言电子英汉词典编程报告,电子英汉词典的编程C语言报告.doc
课程设计(论文) 课 题: 电子英汉词典的编程 学 院: 专 业: 学生姓名: 学 号: 指导老师 : 目录 *内容摘要-----------.---..-------------..3 *关键词-- ...
- 通过游戏编程学Python(6)— 英汉词典、背单词
通过游戏编程学Python 通过游戏编程学Python(番外篇)- 乱序成语.猜单词 通过游戏编程学Python(5)- 猜成语(下) 通过游戏编程学Python(4)- 猜成语(上) 文章目录 通过 ...
最新文章
- 高级软件工程第二次作业
- leetcode算法题--叶值的最小代价生成树
- datatables设置解析
- Spring中的ModelAndView
- jquery find 找到frame select_简述jQuery
- java串口发送16进制数据_MFC串口通信发送16进制数据的方法
- 计算机基础教育学,计算机基础教育教学改革与创新
- 基于Matlab的跨孔CT胖射线追踪算法(三)
- iOS之StatusBar详解
- 教你一键式下载iOS旧版APP(2021年有效)
- 快手视频以及评论获取
- 解决Win10无法安装运行SqlServer 2000
- 什么是物联网(IoT)?
- 全球爆发计算机勒索病毒
- ***【九度oj-1343】城际公路网
- Android客户端与PC服务器实现Socket通信
- 网易163邮箱配置-iOS、OS X邮箱客户端
- 拼多多新手商家开直通车一定要避免的雷区有哪些?
- 《计算机网络自顶向下方法》读书笔记(五):链路层和局域网
- 代码行为异常容错机制与自我调节