ser.c:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sqlite3.h>
struct msg
{
int sfd_new;
struct sockaddr_in cin;
sqlite3* db;
};
int tcpini(struct msg);
void* rcvsend(void* arg);
int cidian(sqlite3* db);
int enroll(int sfd_new,sqlite3* db,char buf[]);
int login(int sfd_new,sqlite3* db,char buf[],char **user);
int inquire(int sfd_new,sqlite3* db,char buf[],char user[]);
int history(int sfd_new,sqlite3* db,char buf[],char user[]);
int quit(int sfd_new,sqlite3* db,char user[]);
int main(int argc, const char *argv[])
{
sqlite3* db=NULL;
if(sqlite3_open("./my.db",&db)!=SQLITE_OK)
{
fprintf(stderr,"line:%d sqlite3_open:%s\n",__LINE__,sqlite3_errmsg(db));
return -1;
}
printf("database open success\n");
cidian(db);//导入词库
struct msg temp;
temp.db=db;
tcpini(temp);//tcp多线程服务器
return 0;
}
int cidian(sqlite3* db)
{
//创建一个word表格
char sql[128]="create table word (wordname char,mean char)";
char* errmsg=NULL;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
if(sqlite3_errcode(db)==1)
{
printf("表格已存在,无需再次导入\n");
return 0;
}
fprintf(stderr,"line:%d sqlite3_exec:%s\n",__LINE__,errmsg);
return -1;
}
printf("create word table success\n");
//导入单词
FILE *fd=fopen("./111.txt","r");
char res[512]="";
char word[32]="";
char mean[256]="";
char *p=NULL;
printf("<<<导入词库中>>>\n");
while(fgets(res,100,fd)!=NULL)
{
res[strlen(res)-1] = 0;
p=res;
while(*p!=' '||*(p+1)!=' ')
{
p++;
}
*p='\0';
strcpy(word,res);
strcpy(mean,p+3);
sprintf(sql,"insert into word values(\"%s\",\"%s\")",word,mean);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"line:%d sqlite3_exec:%s\n",__LINE__,errmsg);
return -1;
}
}
printf("导入成功\n");
/* //关闭数据库
if(sqlite3_close(db)!=SQLITE_OK)
{
fprintf(stderr,"line:%d sqlite3_close:%s\n",__LINE__,sqlite3_errmsg(db));
fprintf(stderr,"line:%d sqlite3_close:%s\n",__LINE__,sqlite3_errmsg(db));
return -1;
}
printf("database close success\n");*/
return 0;
}
int tcpini(struct msg temp)
{
//套接字
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd<0)
{
perror("sfd");
return -1;
}
//允许端口快速被重用
int reuse = 1;
if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse ,sizeof(reuse)) < 0)
{
perror("setsockopt");
return -1;
}
//bind绑定
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(8888);
sin.sin_addr.s_addr=inet_addr("192.168.10.182");
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
{
perror("bind");
return -1;
}
//listen
if(listen(sfd,128)<0)
{
perror("listen");
return -1;
}
printf("服务器监听成功\n");
//accept
struct sockaddr_in cin;
socklen_t len=sizeof(cin);
pid_t pid;
int sfd_new=0;
struct msg info;
while(1)
{
sfd_new=accept(sfd,(struct sockaddr*)&cin,&len);
if(sfd_new<0)
{
perror("accept");
return -1;
}
printf("[%s:%d] newfd = %d 连接成功\n", \
inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), sfd_new);
info.sfd_new=sfd_new;
info.cin=cin;
info.db=temp.db;
//线程
pthread_t pid;
//recv
if(pthread_create(&pid,NULL,rcvsend,(void*)&info)<0)
{
perror("pthread_create");
return -1;
}
//分离线程
pthread_detach(pid);
}
close(sfd);
return 0;
}
void* rcvsend(void* arg)//分线程进行交互
{
char buf[128]="";
char user[32]="";
char sql[128]="";
char *p=user;
char *errmsg=NULL;
ssize_t res=0;
int sfd_new=((struct msg*)arg)->sfd_new;
struct sockaddr_in cin=((struct msg*)arg)->cin;
while(1)
{
//接收客户端请求
bzero(buf,sizeof(buf));
res=recv(sfd_new,buf,sizeof(buf),0);
if(res==0)
{
printf("客户端关闭\n");
//取消该客户端登录信息
sprintf(sql,"UPDATE user SET flag='0' WHERE name='%s';",user);
if(sqlite3_exec(((struct msg*)arg)->db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"line:%d sqlite3_exec:%s error_code:%d\n",__LINE__,errmsg,sqlite3_errcode(((struct msg*)arg)->db));
pthread_exit(NULL);
}
break;
}
else if(res<0)
{
perror("recv");
break;
}
//判断操作码 1.注册 2.登录 3.查询 4.历史记录 5.退出登录
if(1==buf[0])
{
printf("注册\n");
enroll(sfd_new,((struct msg*)arg)->db,buf);
}
else if(2==buf[0])
{
printf("登录\n");
login(sfd_new,((struct msg*)arg)->db,buf,&p);
}
else if(3==buf[0])//查询
{
inquire(sfd_new,((struct msg*)arg)->db,buf,user);
}
else if(4==buf[0])
{
history(sfd_new,((struct msg*)arg)->db,buf,user);
}
else if(5==buf[0])
{
quit(sfd_new,((struct msg*)arg)->db,user);//退出登录,登录状态置0
}
}
close(sfd_new);
pthread_exit(NULL);
}
int enroll(int sfd_new,sqlite3* db,char buf[])
{
char sql[128]="";
char* errmsg=NULL;
char name[32]="";
char passwd[32]="";
strcpy(name,buf+1);
strcpy(passwd,buf+1+strlen(name)+1);
//创建一个user表格
bzero(sql,sizeof(sql));
strcpy(sql,"create table if not exists user (name char PRIMARY KEY,passwd char,flag char)");
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"line:%d sqlite3_exec:%s\n",__LINE__,errmsg);
return -1;
}
//插入用户信息
sprintf(sql,"insert into user values(\"%s\",\"%s\",'0')",name,passwd);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
if(sqlite3_errcode(db)==19)
{
sprintf(sql,"%c%s",0,"Registration failed with duplicate username");
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
return -1;
}
}
fprintf(stderr,"line:%d sqlite3_exec:%s error_code:%d\n",__LINE__,errmsg,sqlite3_errcode(db));
return -1;
}
sql[0]=1;
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
return -1;
}
return 0;
}
int login(int sfd_new,sqlite3* db,char buf[],char **user)//登录
{
//取出用户名和密码
char sql[128]="";
char* errmsg=NULL;
char name[32]="";
char passwd[32]="";
strcpy(name,buf+1);
strcpy(passwd,buf+1+strlen(name)+1);
//判断对与否
sprintf(sql,"select * from user where name='%s';",name);
char **result=NULL;
if(sqlite3_get_table(db,sql,&result,NULL,NULL,&errmsg)!=0)
{
fprintf(stderr,"line:%d sqlite3_get_table:%s\n",__LINE__,errmsg);
}
if(*result==NULL)//判断用户名是否存在
{
sprintf(sql,"%c%s",0,"The user name does not exist");
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
}
return -1;
}
if(strcmp(*(result+4),passwd)!=0)//判断密码是否正确
{
sprintf(sql,"%c%s",0,"The password is incorrect");
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
}
return -1;
}
//账号密码正确,判断登录状态
if(*(result+5)[0]=='0')
{
sql[0]=1;
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
return -1;
}
}
else
{
sprintf(sql,"%c%s",0,"Login failed, repeated login");
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
}
return -1;
}
strcpy(*user,name);//登录成功,保存用户名
//登录状态置1
sprintf(sql,"UPDATE user SET flag='1' WHERE name='%s';",name);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"line:%d sqlite3_exec:%s error_code:%d\n",__LINE__,errmsg,sqlite3_errcode(db));
return -1;
}
return 0;
}
int inquire(int sfd_new,sqlite3* db,char buf[],char user[])//查询
{
char sql[128]="";
char* errmsg=NULL;
char word[32]="";
int row,column;
time_t t;
struct tm* info=NULL;
char h_time[128]="";
//取出word
strcpy(word,buf+1);
//创建一个history表格
bzero(sql,sizeof(sql));
sprintf(sql,"create table if not exists %s_history (word char,mean char,time char)",user);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"line:%d sqlite3_exec:%s\n",__LINE__,errmsg);
return -1;
}
sprintf(sql,"select * from word where wordname=\"%s\";",word);
char **result=NULL;
if(sqlite3_get_table(db,sql,&result,&row,&column,&errmsg)!=0)
{
fprintf(stderr,"line:%d sqlite3_get_table:%s\n",__LINE__,errmsg);
}
if(*result==NULL)//没有单词
{
sprintf(sql,"%c%s%c",0,"The word does not exist",0);
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
}
return -1;
}
//发送单词意思,插入历史记录
bzero(sql,sizeof(sql));
int i = 0;
for(i=3; i<(row+1)*column; i+=2)
{
bzero(sql,sizeof(sql));
sprintf(sql,"%c%s%c",1,*(result+i),0);
if(send(sfd_new,sql,sizeof(sql),0)<0)//发送单词
{
perror("send");
return -1;
}
t=time(NULL);
info=localtime(&t);
sprintf(h_time,"%d-%02d-%02d-%02d-%02d-%02d%c",info->tm_year+1900,\
info->tm_mon+1, info->tm_mday, info->tm_hour,\
info->tm_min, info->tm_sec,0);
sprintf(sql,"insert into %s_history values(\"%s\",\"%s\",'%s')",user,word,*(result+i),h_time);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"line:%d sqlite3_exec:%s error_code:%d\n",__LINE__,errmsg,sqlite3_errcode(db));
return -1;
}
}
sprintf(sql,"%c",2);
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
return -1;
}
return 0;
}
int history(int sfd_new,sqlite3* db,char buf[],char user[])
{
char sql[128]="";
char* errmsg=NULL;
int row,column;
sprintf(sql,"select * from %s_history;",user);
char **result=NULL;
if(sqlite3_get_table(db,sql,&result,&row,&column,&errmsg)!=0)
{
fprintf(stderr,"line:%d sqlite3_get_table:%s\n",__LINE__,errmsg);
}
if(*result==NULL)//没有记录
{
sprintf(sql,"%c%s%c",0,"The history table is empty",0);
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
}
return -1;
}
//发送每一条历史记录
bzero(sql,sizeof(sql));
int i = 0;
for(i=3; i<(row+1)*column; i+=3)
{
bzero(sql,sizeof(sql));
sprintf(sql,"%c%s\t%s\t%s%c",1,*(result+i),*(result+i+1),*(result+i+2),0);
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
return -1;
}
}
sprintf(sql,"%c",2);
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
return -1;
}
}
int quit(int sfd_new,sqlite3* db,char user[])
{
char sql[128]="";
char *errmsg=NULL;
//取消该客户端登录信息
sprintf(sql,"UPDATE user SET flag='0' WHERE name='%s';",user);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"line:%d sqlite3_exec:%s\n",__LINE__,errmsg);
pthread_exit(NULL);
}
sprintf(sql,"%c",2);
if(send(sfd_new,sql,sizeof(sql),0)<0)
{
perror("send");
return -1;
}
}
cil.c:
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int cilini(int* sfd);
int page1(int sfd);
int enroll(int sfd);
int login(int sfd);
int page2(int sfd);
int inquire(int sfd);
int history(int sfd);
int quit(int sfd);
int main(int argc, const char *argv[])
{
int sfd=0;
cilini(&sfd);
page1(sfd);//注册登录页面
//关闭文件描述符
close(sfd);
return 0;
}
int cilini(int* sfd)
{
//创建报式套接字
*sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd < 0)
{
perror("socket");
return -1;
}
//填充服务器地址信息结构体
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(8888);
sin.sin_addr.s_addr=inet_addr("192.168.10.182");
//connect
if(connect(*sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
{
perror("connect");
return -1;
}
printf("服务器连接成功\n");
}
int page1(int sfd)
{
char c = 0;
while(1)
{
system("clear");
printf("**************************\n");
printf("*******1. 注册 *********\n");
printf("*******2. 登录 *********\n");
printf("*******3. 退出 *********\n");
printf("**************************\n");
printf("请输入>>>");
c = getchar();
while(getchar()!=10);
switch(c)
{
case '1':
enroll(sfd);
break;
case '2':
login(sfd);
break;
case '3':
return 0;
default:
printf("输入错误,请重新输入\n");
}
printf("输入任意字符回车清屏>>>");
while(getchar() !=10);
}
return 0;
}
int enroll(int sfd)
{
char buf[128]="";
char name[32] = "";
char passwd[32] = "";
bzero(name, sizeof(name));
printf("请输入用户名>>>");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = 0;
bzero(passwd, sizeof(passwd));
printf("请输入密码>>>");
fgets(passwd, sizeof(passwd), stdin);
passwd[strlen(passwd)-1] = 0;
//注册请求包
bzero(buf,sizeof(buf));
int size = sprintf(buf, "%c%s%c%s%c",1,name,0,passwd,0);
if(send(sfd, buf, size, 0) < 0)
{
perror("send");
return -1;
}
if(recv(sfd,buf,sizeof(buf),0)<0)
{
perror("recv");
return -1;
}
if(buf[0]==1)
{
printf("%s注册成功\n",name);
}
else
{
printf("!!!!!!!!!!!!!!!!!!\n");
printf("%s\n",buf+1);
printf("!!!!!!!!!!!!!!!!!!\n");
}
return 0;
}
int login(int sfd)
{
char buf[128]="";
char name[32] = "";
char passwd[32] = "";
bzero(name, sizeof(name));
printf("请输入用户名>>>");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = 0;
bzero(passwd, sizeof(passwd));
printf("请输入密码>>>");
fgets(passwd, sizeof(passwd), stdin);
passwd[strlen(passwd)-1] = 0;
//登录请求包
bzero(buf,sizeof(buf));
int size = sprintf(buf, "%c%s%c%s%c",2,name,0,passwd,0);
if(send(sfd, buf, size, 0) < 0)
{
perror("send");
return -1;
}
if(recv(sfd,buf,sizeof(buf),0)<0)
{
perror("recv");
return -1;
}
if(buf[0]==1)
{
page2(sfd);
}
else
{
printf("!!!!!!!!!!!!!!!!!!\n");
printf("%s\n",buf+1);
printf("!!!!!!!!!!!!!!!!!!\n");
}
return 0;
}
int page2(int sfd)
{
char c = 0;
while(1)
{
system("clear");
printf("**************************\n");
printf("*******1. 查询 *********\n");
printf("*******2.历史记录*********\n");
printf("*******3. 退出 *********\n");
printf("**************************\n");
printf("请输入>>>");
c = getchar();
while(getchar()!=10);
switch(c)
{
case '1':
inquire(sfd);//查询
break;
case '2':
history(sfd);
break;
case '3':
quit(sfd);
return 0;
break;
default:
printf("输入错误,请重新输入\n");
}
printf("输入任意字符回车清屏>>>");
while(getchar() !=10);
}
return 0;
}
int inquire(int sfd)
{
char buf[128]="";
char word[32]="";
bzero(buf,sizeof(buf));
printf("请输入要查询的单词>>>");
fgets(word, sizeof(word), stdin);
word[strlen(word)-1] = 0;
//查询请求包
bzero(buf,sizeof(buf));
int size = sprintf(buf, "%c%s%c",3,word,0);
if(send(sfd, buf, size, 0) < 0)
{
perror("send");
return -1;
}
while(1)
{
bzero(buf,sizeof(buf));
if(recv(sfd,buf,sizeof(buf),0)<0)
{
perror("recv");
return -1;
}
if(buf[0]==1)
{
printf("%s\t%s\n",word,buf+1);
}
else if(buf[0]==0)
{
printf("!!!!!!!!!!!!!!!!!!\n");
printf("%s\n",buf+1);
printf("!!!!!!!!!!!!!!!!!!\n");
break;
}
else if(buf[0]==2)
{
break;
}
}
return 0;
}
int history(int sfd)
{
char buf[128]="";
//查看历史记录请求包
bzero(buf,sizeof(buf));
int size = sprintf(buf, "%c",4);
if(send(sfd, buf, size, 0) < 0)
{
perror("send");
return -1;
}
while(1)
{
bzero(buf,sizeof(buf));
if(recv(sfd,buf,sizeof(buf),0)<0)
{
perror("recv");
return -1;
}
if(buf[0]==1)
{
printf("%s\n",buf+1);
}
else if(buf[0]==0)
{
printf("!!!!!!!!!!!!!!!!!!\n");
printf("%s\n",buf+1);
printf("!!!!!!!!!!!!!!!!!!\n");
return -1;
}
else if(buf[0]==2)
{
break;
}
}
}
int quit(int sfd)
{
char buf[128]="";
//查看历史记录请求包
bzero(buf,sizeof(buf));
int size = sprintf(buf, "%c",5);
if(send(sfd, buf, size, 0) < 0)
{
perror("send");
return -1;
}
bzero(buf,sizeof(buf));
if(recv(sfd,buf,sizeof(buf),0)<0)
{
perror("recv");
return -1;
}
if(buf[0]==2)
{
printf("退出登录成功\n");
}
return 0;
}