[C] 基于TCP及sqlite3的在线查询词典的简单代码..编程小白,代码可能比较冗长,请各位大佬指出不足 [*・ω・]
功能
- 注册,登录,退出
- 查询单词
- 查询历史记录
运行现象
- 客户端注册及登录(有注册时用户名重复的判断,但图片没有体现)
- 客户端登录成功后查询单词
- 历史查询以及退出(这里服务器代码打印了两遍数据,这个问题已经在下面贴出的代码里修改)
框架以及思路
- 使用TCP实现多个客户端与服务器连接有多线程,多进程,IO多路复用等多种方式,这里我用的是IO多路复用中的epoll函数族.
- 因为涉及到用户的登录以及注册,所以我们需要在数据库中创建一个user表,用来存储用户的用户名以及密码.
- 登录前和登录后头部的提示信息是不同的,因此我们需要声明一个标志变量,用这个变量来判断当前这个客户端是否登录成功
- 通过sqlite3的查询语句来查找user表中是否存在从客户端发来的数据.以此来判断客户端是否可以注册或登录.
- 实现查询单词功能,只需要用fgets逐条获取单词文件的每条数据与客户端发来的数据进行比对即可.
- 要实现查询记录的功能,我们需要为每一个用户创建一个表.因此我们在用户注册成功的时候创建一个名为用户名的表即可.
- 因为要实现的功能比较多,我们最好将一个结构体作为客户端与服务端之间收发数据的载体.因为结构体中我们可以声明一个标志变量,用来让客户端或服务端来判断数据的处理方式.
程序源码(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>
#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*);
int myperror(int,char*);
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;
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])
};
flag = bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
myperror(flag,"bind");
flag = listen(sockfd,6);
myperror(flag,"listen");
struct epoll_event event;
struct epoll_event events[10];
int epollfd = epoll_create(1);
myperror(epollfd,"epoll_create");
event.data.fd = sockfd;
event.events = EPOLLIN|EPOLLET;
flag = epoll_ctl