在线电子词典项目

该博客介绍了使用C语言开发的在线电子词典项目,涉及用户注册登录验证、服务器端SQLite3数据库操作、TCP/IP通信及多进程交互。用户输入被用于在字典文件中搜索翻译,并能查询历史记录。文章包含服务器和客户端流程图以及源码下载链接,鼓励读者提出改进意见。
摘要由CSDN通过智能技术生成

在线词典实现框架:

在这里插入图片描述

1、在线词典

2、项目功能描述

3、用户注册和登录验证

4、服务器端将用户信息和历史记录保存在数据库中,客户端输入用户名和密码,服务器端在数据库中查找、匹配,返回结果

5、单次在线翻译

6、根据客户端输入的单次在字典文件中搜索

7、历史记录查询

8、项目分析

服务器流程图:

在这里插入图片描述

客户端流程图:

在这里插入图片描述

/*server*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sqlite3.h>
#include <signal.h>
#include <time.h>

#define N 128

#define R 1  //register
#define L 2  //login
#define O 3  //logout
#define M 4  //modify
#define Q 5  //query
#define H 6  //history record
#define DATABASE "my.db"

typedef struct {
   

	int  type;      //类型
	char name[N];   //用户名
	char data[256]; //密钥
	int  flag;      //标识位

}MSG;
//客户端请求处理函数
int do_client(int rws, sqlite3 *db);
//注册处理函数
int do_register(int rws, MSG *msg, sqlite3 *db);
//登录处理函数
int do_login(int rws, MSG *msg, sqlite3 *db);
//注销处理函数
int do_logout(int rws, MSG *msg, sqlite3 *db);
//修改信息函数
int do_modify(int rws,MSG *msg,sqlite3 *db);
//查询单词函数
int do_query(int rws,MSG *msg,sqlite3 *db);
//显示查询记录函数
int do_record(int rws,MSG *msg,sqlite3 *db);


// ./server 192.168.30.202 8888
int main(int argc, const char *argv[])
{
   

	int s = -1;  //监听套接字
	int rws =-1; //读写套接字
	struct sockaddr_in addr;
	char *errmsg;
	pid_t pid;
	//命令行传参	
	if(argc != 3){
   
		printf("Usage: %s <ipstr> <port>.\n", argv[0]);
		return -1;
	}	

	//1.创建套接字
	if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
   
		perror("socket");
		return -1;
		//	exit(-1);
	}

	//2.初始化服务器端地址结构体
	//bzero(&addr, sizeof(addr));
	memset(&addr,0,sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr(argv[1]);
	addr.sin_port = htons(atoi(argv[2]));

	//3.绑定IP和端口
	if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	{
   
		perror("bind");
		goto ERR_STEP;
		//return -1;
		//exit(-1);
	}

	//4.监听套接字
	if(listen(s, 10) < 0)
	{
   
		perror("listen");
		goto ERR_STEP;
		//exit(-1);
	}

	//5.设置套接字端口复用属性
	int on = 1;
	//setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
	{
   
		perror("setsockopt");
		return -1;
	}
	//创建打开数据库
	sqlite3 *db;
	if(sqlite3_open(DATABASE, &db) != SQLITE_OK)
	{
   
		printf("%s\n", sqlite3_errmsg(db));
		return -1;
	}
	else
	{
   
		printf("open Database success\n");
	}
	//需要在数据库中创建两张表:学生信息表和查询记录表
	//创建学生信息表
	//char sql[256]="create table if not exists stu(id integer primary key autoincrement, name text,passwd text);";
	char sql[256]="create table if not exists stu(name text,passwd text);";
	printf("sql=%s\n",sql);//调试信息
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=0)
	{
   
		fprintf(stderr,"create table fail! %s\n",errmsg);
		return -1;
	}
	//创建历史记录信息表
	char sql_history[256]="create table if not exists record(name text,datetime text,word text);";
	printf("sql_history=:%s\n",sql_history);//调试信息
	if(sqlite3_exec(db,sql_history,NULL,NULL,&errmsg)!=0)
	{
   
		fprintf(stderr,"create table fail! %s\n",errmsg);
		return -1;
	}
	printf("-------------------准备事项均已成功创建!-------------------------\n");
	printf("-------------------接下来等待客户链接请求-------------------------\n");

	//父进程接收子进程的退出信号
	signal(SIGCHLD, SIG_IGN);

	//6.循环处理客户端的链接服务请求
	while(1)
	{
   
		printf("wait for client...\n");
#if 0
		/*如需打印连接的客户端信息,则开启此段代码*/
		struct sockaddr_in cliaddr;
		socklen_t clilen=sizeof(cliaddr);
		rws=accept(s,(struct sockaddr*)&cliaddr,&clilen);
		//if(0 >(rws=accept(s,(struct sockaddr*)&cliaddr,&clilen));
		char buf[INET_ADDRSTRLEN]={
   };
		if(inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,buf,INET_ADDRSTRLEN))
		{
   
			printf("client ip:%s ",buf);
		}
		printf("port:%u\n",ntohs(cusaddr.sin_port));
#endif
#if 1
		if((rws = accept(s, NULL, NULL)) < 0)
		{
   
			perror("accept");
			exit(-1);
		}
#endif
		//调用fork函数创建子进程
		if((pid = fork()) < 0)
		{
   
			perror("fork");
			exit(-1);
		}
		else if(pid == 0)
		{
   
			//子进程负责处理客户端发来的链接请求
			close(s);                       //不需要监听套接字,关闭
			do_client(rws, db)
  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在线词典项目描述: 版本号:v1.1 升级描述:1. 同时支持管理员(用户名:root,密码:1)和普通用户 2. 管理员可以查询所有用户的使用记录 服务器: 1. 支持并发服务器,每有一个客户端connect成功后,提示某某客户端已连接并打印客户端的ip和端口号。 2. 服务器程序可在任意IP地址上运行,并且允许IP地址快速重用 3. 接收到客户端的信息后,可以执行相应的操作:注册,登陆,退出 注册:接收到注册新用户指令后,可以创建sqlite3数据库,将用户名和密码存储到数据库的user表中(用户名name为primary key)。 登陆:接收到登陆命令,可以查询客户端输入的用户名和密码数据库中有没有,有的话跳到下一个菜单(查询单词,历史纪录,退出),没有的话打印错误信息。 查询单词:用户输入单词,服务器从dict.txt文件中遍历有无该单词,有的话打印释义,没有的话打印错误信息,并将用(户名,时间,单词)存储到数据库的history_record表中。(‘#’返回上一级菜单) 历史纪录:用户选择历史记录查询,服务器从数据库的history_record表查询相同name的记录,每查询到一条,调用一次callback将信息发送到客户端,查询完毕后通知客户端。 退出:客户端退出,服务器打印"client exit!" 退出:客户端退出,服务器打印"client exit!" 客户端: 1. 客户端输入./client 192.168.23.128(服务器IP地址) 10000(端口号),参数格式不对或少报错,端口号不能小于5000,小于5000报错 2. 客户端支持注册,登陆,退出 注册:向服务器发送用户名和密码,接收服务器返回来的信息,注册成功/当前用户已存在 登陆:用户输入用户名和密码,客服端将用户名和密码发送给服务器,接收服务器返回的信息,如果OK,打印Login OK! 进入下一菜单(查询单词,历史纪录,退出),否则打印错误信息 查询单词:用户输入单词,客户端将单词发送给服务器,服务器将释义返回给客户端,客户端将释义打印出来 历史纪录:用户选择历史记录查询,客户端将信息发送给服务器,服务器循环把该用户的历史查询记录发送给客户端,客户端循环将其打印出来。 退出:客户端关闭套接字后结束进程 退出:客户端关闭套接字后结束进程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值