客服端的代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <sqlite3.h>
//client.c
#define N 16
#define R 1 // user register
#define L 2 // user login
#define Q 3 // query word
#define H 4 // history record
#define L_not 5 //登录失败
#define R_success 6 //注册成功
void print1(){
printf("-------------------------------------\n");
printf("| 1.注册 2:登录 3:退出 |\n");
printf("-------------------------------------\n");
printf("请输入你需要的功能");
}
void print2(){
printf("-------------------------------------\n");
printf("| 1.查找单词 2:历史记录 3:退出 |\n");
printf("-------------------------------------\n");
printf("请输入你需要的功能");
}
int flag=0;
struct MSG{
char type;
char name[30];
char data[256];
};
struct MSG msg;
void do_register(int socketfd,struct MSG *msg){
char name[50];
char password[200];
printf("请输入用户名:");
scanf("%s",msg->name);
printf("请输入密码:");
scanf("%s",msg->data);
msg->type=R;
if(-1==send(socketfd,msg,sizeof(struct MSG),0)){
perror("send error ");
exit(0);
}
if(-1==recv(socketfd,msg,sizeof(struct MSG),0)){
perror("recv error ");
exit(0);
}
if(msg->type==R_success){
printf("注册成功\n");
}
return;
}
int login(int socketfd,struct MSG *msg){
;
memset(msg,0,sizeof(struct MSG));
printf("请输入用户名:");
scanf("%s",msg->name);
printf("请输入密码:");
scanf("%s",msg->data);
msg->type=L;//L代表登录
if(-1 == send(socketfd,msg, sizeof(struct MSG), 0)){
perror("send error");
exit(0);
}
memset(msg,0,sizeof(msg));
if(-1 == recv(socketfd, msg, sizeof(struct MSG), 0)){
perror("recv error");
exit(0);
}
if(msg->type==L){
flag=1;
printf("登录成功\n");
return 1;
}else if(msg->type==L_not){
printf("登录失败");
return 0;
}
}
void do_query(int socketfd,struct MSG *msg)
{
msg->type=Q;
printf("请输入单词\n");
scanf("%s",msg->data);
if(-1 == send(socketfd, msg, sizeof(struct MSG), 0)){
perror("send error");
exit(0);
}
if(-1 == recv(socketfd,msg, sizeof(struct MSG), 0)){
perror("recv error");
exit(0);
}
printf("解释:[%s]\n",msg->data);
return;
}
void do_history(int socketfd, struct MSG *msg)
{
msg->type=H;
printf("历史记录:%s\n",msg->name);
if(-1==send(socketfd,msg,sizeof(struct MSG),0)){
perror("send error");
exit(-1);
}
while(1){
recv(socketfd, msg, sizeof(struct MSG), 0);
if(strcmp(msg->data,"**OVER**")==0){
return;
}
printf("%s\n",msg->data);
}
}
int main(int argc,const char *argv[])
{
if (argc < 3)
{
printf("Usage : %s <ip> <port>\n", argv[0]);
exit(-1);
}
struct MSG msg;
memset(&msg,0,sizeof(msg));
int socketfd=socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in serveraddr;
serveraddr.sin_family=AF_INET;
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
serveraddr.sin_port=htons(atoi(argv[2]));
if(connect(socketfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr))){
perror("connect error");
exit(0);
}
int choose=0;
while(1){
print1();
scanf("%d",&choose);
switch(choose){
case 1: do_register(socketfd,&msg);
break;
case 2:
if(login(socketfd,&msg)){
while(1){
print2();
scanf("%d",&choose);
switch(choose)
{
case 1:
do_query(socketfd, &msg);
break;
case 2:
do_history(socketfd, &msg);
break;
case 3:
close(socketfd);
exit(0);
}
}
}
break;
case 3: exit(0);
break;
}
}
return 0;
}
后面是服务端的代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
#include <sqlite3.h>
#include <time.h>
//server.c
#define N 16
#define R 1 // user register
#define L 2 // user login
#define Q 3 // query word
#define H 4 // history record
#define L_not 5 //登录失败
#define R_success 6 //注册成功
struct MSG{
char type;
char name[30];
char data[256];
};
void getdata(char *data)
{
time_t t;
struct tm *tp;
time(&t);
tp = localtime(&t);
sprintf(data, "%d-%d-%d %d:%d:%d", 1900+tp->tm_year, 1+tp->tm_mon, tp->tm_mday, \
tp->tm_hour, tp->tm_min, tp->tm_sec);
}
void do_register(int connectfd,struct MSG *msg,sqlite3 *db){
char sql[512]={0};
sprintf(sql,"insert into usr values('%s','%s')",msg->name,msg->data);
sqlite3_exec(db,sql,NULL,NULL,NULL);
msg->type=R_success;
if(-1==send(connectfd,msg,sizeof(struct MSG),0)){
perror("send error");
exit(0);
}
}
void login(int connectfd,struct MSG *msg,sqlite3 *db,int *flag){
char sql[500]={0};
char *errmsg, **result;
int nrow, ncolumn;
sprintf(sql,"select * from usr where name='%s' and pass='%s'",
msg->name,msg->data);
int row=0;
printf("sql:[%s]",sql);
printf("进入login\n");
if(sqlite3_get_table(db,sql,&result,&row,&ncolumn,&errmsg)!= SQLITE_OK){
printf("error:%s",errmsg);
exit(-1);
}
printf("row=%d\n",row);
if(row>=1) {
*flag=1;
if(-1 == send(connectfd,msg, sizeof(struct MSG), 0)){
perror("send error");
exit(0);
}
}else{
msg->type=L_not;
if(-1 == send(connectfd,msg, sizeof(struct MSG), 0)){
perror("send error");
exit(0);
}
}
}
void do_query(int connectfd,struct MSG *msg, sqlite3 *db)
{
int nbytes=0;
FILE *fp;
if(NULL==(fp=fopen("dict.txt","r"))){
perror("fopen error");
exit(-1);
}
char word[300]={0};
sprintf(word,"%s ",msg->data);
char buff[256]={0};
while(fgets(buff,256,fp)){
if(0==strncmp(buff,word,strlen(word))){
char *p;
p=buff;
while(*p!=' '){
p++;
}
while(*p==' '){
p++;
}
sprintf(msg->data,"%s",p);
printf("yfs:[%s]\n",p);
if(-1 == send(connectfd, msg, sizeof(struct MSG), 0)){
perror("send error");
exit(-1);
}
char sql[128]={0};
char date[100]={0};
getdata(date);
sprintf(sql,"INSERT INTO record VALUES('%s','%s','%s')",
msg->name,date,word);
sqlite3_exec(db,sql,NULL,NULL,NULL);
return;
}
}
printf("找不到该单词");
return;
}
int callback(void *arg,int column,char** f_value,char** f_name){
struct MSG msg;
memset(&msg,0,sizeof(struct MSG));
sprintf(msg.data,"%s|%s",f_value[1],f_value[2]);
if(-1==send(*(int *)arg,&msg,sizeof(struct MSG),0)){
perror("send error");
exit(-1);
}
return 0;
}
void do_history(int connectfd, struct MSG *msg, sqlite3 *db)
{
printf("name=%s\n",msg->name);
char sql[128]={0},*errmsg;
sprintf(sql,"select * from record where name='%s'",msg->name);
if(SQLITE_OK!=sqlite3_exec(db,sql,callback,&connectfd,&errmsg)){
printf("sqlite3_exec[%s]",errmsg);
exit(-1);
}
strcpy(msg->data, "**OVER**");
send(connectfd, msg, sizeof(struct MSG), 0);
}
int main(int argc,const char *argv[])
{
if (argc < 3)
{
printf("Usage : %s <ip> <port>\n", argv[0]);
exit(-1);
}
//打开数据库
sqlite3 *my_db;
int ret = sqlite3_open("my.db", &my_db);
if(SQLITE_OK != ret){
printf("errcode:[%d] errstr:[%s]\n", ret, sqlite3_errmsg(my_db));
exit(-1);
}
//执行sql语句
#if 0
int sqlite3_exec(
sqlite3* db, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *arg, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
#endif
//创建第一个表用来存储用户信息
char* sql = "create table if not exists usr (name text primary key, pass text);" ;
char* errmsg = NULL;
if(sqlite3_exec(my_db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
return -1;
}
printf("create table success\n");
//创建第二个表用来存查看记录
char* sql2 = "create table if not exists usr1 (name text,data text, word text);" ;
char* errms = NULL;
if(sqlite3_exec(my_db, sql2, NULL, NULL, &errms) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errms);
return -1;
}
printf("create table success\n");
struct MSG msg;
int listenfd=0;
int connectfd=0;
struct sockaddr_in serveraddr;
serveraddr.sin_family=PF_INET;
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
serveraddr.sin_port=htons(atoi(argv[2]));
if ((listenfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
perror("fail to socket");
exit(-1);
}
if(-1==(bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr)))){
perror("bind error");
}
if(listen(listenfd,5)<0){
perror("listen error");
exit(-1);
}
int pid;
while(1){
if((connectfd=accept(listenfd,NULL,NULL))<0){
perror("accept error");
exit(-1);
}
if((pid=fork())<0){
perror("fork error");
exit(0);
}
else if(pid==0){
printf("进入子进程\n");
while(recv(connectfd, &msg, sizeof(msg), 0) > 0){
printf("进入while循环\n");
printf("type:%d\n",msg.type);
int flag=0;//标志是否登录0为没登录
switch(msg.type){
case 1: do_register(connectfd,&msg,my_db);
break;
case L:
printf("进入L\n");
login(connectfd,&msg,my_db,&flag);
break;
case 3: do_query(connectfd,&msg, my_db);
break;
case 4: do_history(connectfd, &msg, my_db);
}
}
}else{
//父进程
}
}
return 0;
}