客户端
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__\n",__LINE__);\
perror(msg);\
}while(0)
struct User
{
int type;
int isLogin;
char name[30];
char text[128];
}msg;
typedef void (*sighandler_t)(int);
int sfd;
char name[30];
void handler(int sig)
{
msg.type=0;
if(send(sfd,&msg,sizeof(msg),0)<0)
{
ERR_MSG("recv");
return ;
}
printf("用户%s退出登录\n",msg.name);
exit(0);
}
int main(int argc, const char *argv[])
{
sighandler_t s=signal(2,handler);
if(SIG_ERR==s)
{
ERR_MSG("signal");
return -1;
}
if(argc<3)
{
fprintf(stderr,"入参不够\n");
return -1;
}
int port=atoi(argv[2]);
if(port<1024 || port>49515)
{
fprintf(stderr,"端口号超出范围\n");
return -1;
}
sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd<0)
{
ERR_MSG("socket");
return -1;
}
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(port);
sin.sin_addr.s_addr=inet_addr(argv[1]);
connect(sfd,(struct sockaddr *)&sin,sizeof(sin));
int choose=0;
while(1)
{
printf("******************\n");
printf("******1.注册******\n");
printf("******2.登录******\n");
printf("******3.查询******\n");
printf("******4.记录******\n");
printf("******************\n");
printf("请输入选项:>>");
scanf("%d",&choose);
getchar();
bzero(&msg,sizeof(msg));
msg.type=choose;
switch(choose)
{
case 1:
printf("请输入要注册的用户名:>>");
fgets(msg.name,sizeof(msg.name),stdin);
msg.name[strlen(msg.name)-1]=0;
break;
case 2:
printf("请输入要登录的用户名:>>");
fgets(msg.name,sizeof(msg.name),stdin);
msg.name[strlen(msg.name)-1]=0;
strcpy(name,msg.name);
break;
case 3:
printf("请输入要查询的单词:>>");
fgets(msg.text,sizeof(msg.text),stdin);
msg.text[strlen(msg.text)-1]=0;
strcpy(msg.name,name);
break;
case 4:
strcpy(msg.name,name);
break;
default:
printf("输入选项错误\n");
}
if(send(sfd,&msg,sizeof(msg),0)<0)
{
ERR_MSG("recv");
return -1;
}
if(recv(sfd, &msg, sizeof(msg), 0)<0)
{
ERR_MSG("recv");
return -1;
}
if(msg.type>=10)
printf("%s\n",msg.text);
else
printf("%s\n\n",msg.text);
if(msg.type>=10)
{
int flagHistory=msg.type/10;
for(int i=0;i<flagHistory-1;i++)
{
if(recv(sfd, &msg, sizeof(msg), 0)<0)
{
ERR_MSG("recv");
return -1;
}
printf("%s\n",msg.text);
}
}
}
return 0;
}
~
~
~
服务器
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <time.h>
#define ERR_MSG(msg) do{\
fprintf(stderr, " __%d__ ", __LINE__);\
perror(msg);\
}while(0)
#define PORT 8888
#define IP "192.168.1.42"
struct User
{
int type;
int isLogin;
char name[30];
char text[128];
}msg;
typedef void (*sighandler_t)(int);
int rcv_cli_msg(int newfd, struct sockaddr_in cin);
int do_insert(sqlite3 *db,char *name);
int do_update_user(sqlite3 *db,char *name);
int do_update_user_close(sqlite3 *db,char *name);
int do_select_user(sqlite3 *db,char *name);
int do_select_word(sqlite3 *db,char *text);
int do_select_history(sqlite3 *db,char *name);
int do_select_history_print(sqlite3 *db,char *name,int newfd);
int callback(void *arg,int len,char **value,char **name);
int callbackWord(void *arg,int len,char **value,char **name);
int callbackHistory(void *arg,int len,char **value,char **name);
int callbackHistoryPrint(void *arg,int len,char **value,char **name);
int flag=0,flagWord=0,flagHistory=0,fhi=0;
int isLogin=0;
void handler(int sig)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}
int main(int argc, const char *argv[])
{
sighandler_t s = signal(17, handler);
if(SIG_ERR == s)
{
ERR_MSG("signal");
return -1;
}
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("create socket success\n");
int reuse = 1;
if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
{
ERR_MSG("setsockopt");
return -1;
}
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
{
ERR_MSG("bind");
return -1;
}
printf("bind success\n");
if(listen(sfd, 10) < 0)
{
ERR_MSG("listen");
return -1;
}
printf("listen success\n");
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
int newfd = 0;
pid_t pid = 0;
while(1)
{
newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);
if(newfd < 0)
{
perror("accept");
return -1;
}
printf("[%s : %d] newfd = %d\n", inet_ntoa(cin.sin_addr),
ntohs(cin.sin_port),newfd);
pid = fork();
if(pid > 0)
{
close(newfd);
}
else if(0 == pid)
{
close(sfd);
rcv_cli_msg(newfd, cin);
close(newfd);
exit(0);
}
else
{
ERR_MSG("fork");
return -1;
}
}
close(sfd);
return 0;
}
int rcv_cli_msg(int newfd, struct sockaddr_in cin)
{
ssize_t res = 0;
sqlite3* db=NULL;
if(sqlite3_open("./my.db",&db)!=SQLITE_OK)
{
printf("err_code:%d\n",sqlite3_errcode(db));
printf("errmsg:%s\n",sqlite3_errmsg(db));
fprintf(stderr,"__%d__sqlite3_open failed\n",__LINE__);
return -1;
}
printf("sqlite3 open success\n");
while(1)
{
bzero(&msg,sizeof(msg));
res = recv(newfd, &msg, sizeof(msg), 0);
if(res < 0)
{
ERR_MSG("recv");
return -1;
}
else if(0 == res)
{
printf("[%s : %d] newfd = %d client off-line\n",
inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),newfd);
break;
}
printf("[%s : %d] newfd = %d :%d %s\n", inet_ntoa(cin.sin_addr),
ntohs(cin.sin_port),newfd,msg.type, msg.name);
switch(msg.type)
{
case 0:
do_update_user_close(db,msg.name);
break;
case 1:
//如果注册成功,插入数据到数据库,否则提示注册失败
if(do_insert(db,msg.name)!=0)
{
strcpy(msg.text,"用户名已经注册");
}
else
{
strcpy(msg.text,"注册成功\n");
}
break;
case 2:
//如果登录成功,则要提示登录成功,否则提示登录失败
if(isLogin==0)
{
if(do_update_user(db,msg.name)!=0)
{
strcpy(msg.text,"用户名不存在或该账号已登录\n");
}
else
{
strcpy(msg.text,"登录成功\n");
isLogin=1;
}
}
else
{
strcpy(msg.text,"请先退出\n");
}
break;
case 3:
if(isLogin==1)
{
if(do_select_word(db,msg.text)!=0)
{
//strcpy(msg.text,"词典里有该单词\n");
}
else
{
strcpy(msg.text,"词典里没有该单词\n");
}
}
else
{
strcpy(msg.text,"请先登录\n");
}
break;
case 4:
if(isLogin==1)
{
if(do_select_history(db,msg.name)!=0)
{
do_select_history_print(db,msg.name,newfd);
}
else
{
strcpy(msg.text,"该用户没有查询过单词\n");
}
}
else
{
strcpy(msg.text,"请先登录\n");
}
break;
default:
printf("输入选项错误\n");
}
//发送数据
if(send(newfd, &msg, sizeof(msg), 0) < 0)
{
ERR_MSG("send");
return -1;
}
printf("send message success\n");
}
//关闭数据库
if(sqlite3_close(db)!=SQLITE_OK)
{
printf("err_code:%d\n",sqlite3_errcode(db));
printf("errmsg:%s\n",sqlite3_errmsg(db));
fprintf(stderr,"__%d__sqlite3_close failed\n",__LINE__);
return -1;
}
printf("sqlite3_close success\n");
return 0;
}
int do_insert(sqlite3 *db,char *name)
{
char sql[128]="";
char *errmsg=NULL;
sprintf(sql,"insert into user values (\"%s\",\"%d\")",name,0);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=0)
{
return -1;
}
else
{
return 0;
}
}
int do_update_user(sqlite3 *db,char *name)
{
char sql[128]="";
char *errmsg=NULL;
//查找用户
if(do_select_user(db,name)<=0)
{
return -1;
}
sprintf(sql,"update user set isLogin=1 where userName=\"%s\";",name);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=0)
{
return -1;
}
return 0;
}
int do_update_user_close(sqlite3 *db,char *name)
{
char sql[128]="";
char *errmsg=NULL;
sprintf(sql,"update user set isLogin=0 where userName=\"%s\";",name);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=0)
{
return -1;
}
return 0;
}
int do_select_user(sqlite3 *db,char *name)
{
char sql[128]="";
char *errmsg=NULL;
sprintf(sql,"select * from user where userName=\"%s\" and isLogin=0;",name);
//重置flag
flag=0;
if(sqlite3_exec(db,sql,callback,NULL,&errmsg)!=0)
{
return -1;
}
return flag;
}
int callback(void *arg,int len,char **value,char **name)
{
flag++;
return 0;
}
int do_select_word(sqlite3 *db,char *text)
{
char sql[128]="";
char *errmsg=NULL;
sprintf(sql,"select * from dict where word=\"%s\";",text);
//重置flagWord
flagWord=0;
if(sqlite3_exec(db,sql,callbackWord,db,&errmsg)!=0)
{
return -1;
}
return flagWord;
}
int callbackWord(void *arg,int len,char **value,char **name)
{
flagWord++;
//把查询到的结果装入待发送的结构体
strcpy(msg.text,*(value+1));
//获取当前时间
char date[30]="";
time_t t=time(NULL);
struct tm *tm=localtime(&t);
sqlite3* db=(sqlite3 *)arg;
sprintf(date,"%02d-%02d-%02d %02d:%02d:%02d",
tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,
tm->tm_hour,tm->tm_min,tm->tm_sec);
//printf("%s\n",date);
char sql[128]="";
char *errmsg=NULL;
sprintf(sql,"insert into history values (\"%s\",\"%s\",\"%s\",\"%s\");",
msg.name,*value,*(value+1),date);
//printf("%s\n",sql);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=0)
{
return -1;
}
return 0;
}
int do_select_history(sqlite3 *db,char *name)
{
char sql[128]="";
char *errmsg=NULL;
sprintf(sql,"select * from history where userName=\"%s\";",name);
//重置flagHistory
flagHistory=0;
if(sqlite3_exec(db,sql,callbackHistory,NULL,&errmsg)!=0)
{
return -1;
}
return flagHistory;
}
int callbackHistory(void *arg,int len,char **value,char **name)
{
flagHistory++;
return 0;
}
int do_select_history_print(sqlite3 *db,char *name,int newfd)
{
char sql[128]="";
char *errmsg=NULL;
sprintf(sql,"select * from history where userName=\"%s\";",name);
//重置fhi
fhi=0;
if(sqlite3_exec(db,sql,callbackHistoryPrint,&newfd,&errmsg)!=0)
{
return -1;
}
return 0;
}
int callbackHistoryPrint(void *arg,int len,char **value,char **name)
{
//把查询到的结果装入待发送的结构体
int newfd=*(int *)arg;
sprintf(msg.text,"%-10s %-20s %-20s",*(value+1),*(value+2),*(value+3));
//strcpy(msg.text,*(value+1));
msg.type=flagHistory*10;
if(fhi<flagHistory-1)
{
if(send(newfd, &msg, sizeof(msg), 0) < 0)
{
ERR_MSG("send");
return -1;
}
}
return 0;
}
建立词典
#include<stdio.h>
#include<string.h>
#include<sqlite3.h>
#include<stdlib.h>
int do_insert(sqlite3 *db,char *word,char *mean);
int main(int argc, const char *argv[])
{
char buf[128]="";
char *res=NULL,*p=NULL;
char mean[30]="",word[30]="";
char *meanp=NULL,*wordp=NULL;
//打开文件
FILE *fp=fopen("./dict.txt","r");
if(NULL==fp)
{
perror("fopen");
return -1;
}
//读取文件内容
//打开数据库
sqlite3 *db=NULL;
if(sqlite3_open("./my.db",&db)!=SQLITE_OK)
{
printf("err_code:%d\n",sqlite3_errcode(db));
printf("errmsg:%s\n",sqlite3_errmsg(db));
fprintf(stderr,"__%d__sqlite3_open failed\n",__LINE__);
}
printf("sqlite3_open success\n");
//创建一个表格
char *sql="create table if not exists dict (word char,mean char);";
char *errmsg=NULL;
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
{
fprintf(stderr,"__%d__sqlite3_exex:%s\n",__LINE__,errmsg);
return -1;
}
printf("create table success\n");
while(1)
{
bzero(buf,sizeof(buf));
bzero(mean,sizeof(mean));
bzero(word,sizeof(word));
res=fgets(buf,sizeof(buf),fp);
if(res==NULL)break;
p=buf;
meanp=mean;
wordp=word;
while(*p!=' ' || *(p+1)!=' ')
{
if(*p=='\'')
{
printf("yes\n");
*wordp++ = '\'';
printf("%c\n",*(wordp-1));
p++;
continue;
}
*wordp++ = *p++;
}
while(*p==' ')p++;
while(*p!='\n')
{
*meanp++ = *p++;
}
do_insert(db,word,mean);
}
//关闭数据库
if(sqlite3_close(db)!=SQLITE_OK)
{
printf("err_code:%d\n",sqlite3_errcode(db));
printf("errmsg:%s\n",sqlite3_errmsg(db));
fprintf(stderr,"__%d__sqlite3_close failed\n",__LINE__);
return -1;
}
printf("sqlite3_close success\n");
return 0;
}
int do_insert(sqlite3 *db,char *word,char *mean)
{
char sql[128]="";
char * errmsg=NULL;
sprintf(sql,"insert into dict values (\"%s\",\"%s\");",word,mean);
sqlite3_exec(db,sql,NULL,NULL,&errmsg)!=SQLITE_OK;
}