C语言 基于TCP及sqlite3的在线查询词典的简单代码

该博客介绍了一个基于C语言、Linux环境,利用TCP协议和sqlite3数据库实现的在线查询词典的程序。功能包括用户注册、登录、退出、查询单词和历史记录。程序使用IO多路复用中的epoll函数族处理多客户端连接,并通过结构体作为数据载体。存在的问题包括用户名或密码过长未处理、历史记录长度限制、最大连接数限制及单线程导致的潜在崩溃风险。
摘要由CSDN通过智能技术生成

功能

  1. 注册,登录,退出
  2. 查询单词
  3. 查询历史记录

运行现象

  1. 客户端注册及登录(有注册时用户名重复的判断,但图片没有体现)
  2. 客户端登录成功后查询单词
  3. 历史查询以及退出(这里服务器代码打印了两遍数据,这个问题已经在下面贴出的代码里修改)

框架以及思路

  1. 使用TCP实现多个客户端与服务器连接有多线程,多进程,IO多路复用等多种方式,这里我用的是IO多路复用中的epoll函数族.
  2. 因为涉及到用户的登录以及注册,所以我们需要在数据库中创建一个user表,用来存储用户的用户名以及密码.
  3. 登录前和登录后头部的提示信息是不同的,因此我们需要声明一个标志变量,用这个变量来判断当前这个客户端是否登录成功
  4. 通过sqlite3的查询语句来查找user表中是否存在从客户端发来的数据.以此来判断客户端是否可以注册或登录.
  5. 实现查询单词功能,只需要用fgets逐条获取单词文件的每条数据与客户端发来的数据进行比对即可.
  6. 要实现查询记录的功能,我们需要为每一个用户创建一个表.因此我们在用户注册成功的时候创建一个名为用户名的表即可.
  7. 因为要实现的功能比较多,我们最好将一个结构体作为客户端与服务端之间收发数据的载体.因为结构体中我们可以声明一个标志变量,用来让客户端或服务端来判断数据的处理方式.

程序源码(LINUX)

1.head.h(头文件)

#ifndef _HEAD_H_
#define _HEAD_H_

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<linux/in.h>
#include<sys/types.h>          /* See NOTES */
#include<sys/socket.h>
#include<sys/epoll.h>
#include<sqlite3.h>

#define REGIST 	0	//注册
#define LOGIN	1	//登录
#define QUERY	2	//单词查询
#define RENAME	3	//注册时重名
#define UNEXIST	4	//不存在
#define HISTORY 5	//历史查询
#define EMPTY	6	//历史记录为空

//服务端与客户端首发数据所使用的结构体
typedef struct packet{
   
	int flag;			//信息标志
	char username[16];	//用户名
	char arr[192];		//存放主要信息的数组
}packet;


int dbperror(int,char*,char*);	//用于sqlite3相关函数的自定义perror函数
int myperror(int,char*);		//自定义perror函数
void prompt();					//登录前提示信息的打印
void prompt_login();			//登录后提示信息的打印
#endif

2.func_home.c(存放着一些自定义的函数接口)

#include"head.h"


int myperror(int flag,char *name){
   
	if(flag < 0){
   
		printf("%s is error\n",name);
		perror("");
		exit(-1);
		return 0;
	}
	return 0;
}
int dbperror(int flag,char *name,char *error){
   
	if(flag != 0){
   
		fprintf(stderr,"%s is error %s\n",name,error);
		exit(-1);
	}
	return 0;
}
void prompt(){
   

	printf("*************************************\n");
	printf("  *                               *\n");
	printf("  *  1.regist  2.login  3.quit    *\n");
	printf("  *                               *\n");
	printf("*************************************\n");

}
void prompt_login(){
   
	
	printf("*************************************\n");
	printf("  *                               *\n");
	printf("  *  1.query  2.history  3.quit   *\n");
	printf("  *                               *\n");
	printf("*************************************\n");
}

3.server.c(服务端代码)

#include"head.h"


int main(int argc, const char *argv[])
{
   
	int acceptfd,i,j,o,flag,sockfd,num,query_flag,eptc;
	//打开存放单词信息的文件
	FILE *fp = fopen("./dict.txt","r");
	if(!fp){
   
		perror("fopen is error");
		exit(-1);
	}
	char buf[192]= {
   };
	packet data;
	//socket
	sockfd = socket(AF_INET,SOCK_STREAM,0);
	myperror(sockfd,"socket");
	struct sockaddr_in clientaddr;
	size_t clientlen = sizeof(clientaddr);
	struct sockaddr_in serveraddr = {
   		
		.sin_family = AF_INET,
		.sin_port = htons(atoi(argv[2])),
		.sin_addr.s_addr = inet_addr(argv[1])
	};
	//bind
	flag = bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
	myperror(flag,"bind");
	//listen
	flag = listen(sockfd,6);
	myperror(flag,"listen");
	//epoll_event结构体以及数组的声明
	struct epoll_event event;
	struct epoll_event events[10];
	//epoll_create
	int epollfd = epoll_create(1);
	myperror(epollfd,"epoll_create");
	//epoll_ctl
	event.data.fd = sockfd;
	event.events = EPOLLIN|EPOLLET;
	flag = epoll_ctl
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值