一、词典
1、服务器
#include <myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.116.128"
typedef struct acc_pass
{int num;char account[20];int password;
}*acc_pass;
typedef struct search_query
{int num;char word[50];char account[20];
} search_query_t;
typedef struct search_history
{char client_ip[16];int client_port;char account[20];char search_word[50];char search_result[256];char search_time[20];
} search_history_t;
int insert_word(sqlite3 *ppDb,char *buf1,char *buf2)
{char sql[256] = ""; sprintf(sql, "insert into WORD_TRANSLATE values(\"%s\",\"%s\");",buf1,buf2);char *errmsg = NULL; if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d插入失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}return 0;
}
int empty_word(sqlite3 *ppDb)
{char sql[128] = ""; sprintf(sql, "delete from WORD_TRANSLATE;");char *errmsg = NULL; if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d插入失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}return 0;
}
int record_search_history(sqlite3 *ppDb, char *client_ip, int client_port, char *account, char *word, char *result)
{time_t now = time(NULL);struct tm *t = localtime(&now);char timestamp[20];snprintf(timestamp, sizeof(timestamp), "%04d-%02d-%02d %02d:%02d:%02d",t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,t->tm_hour, t->tm_min, t->tm_sec);char sql[512] = ""; sprintf(sql, "insert into SEARCH_HISTORY values(\"%s\", %d, \"%s\", \"%s\", \"%s\", \"%s\");",\client_ip,client_port,account, word, result, timestamp);char *errmsg = NULL; if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d插入搜索历史失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}return 0;
}
int query_word(sqlite3 *ppDb, char *word, char *result, int result_size)
{char sql[256] = ""; sprintf(sql, "select translate from WORD_TRANSLATE where word=\"%s\";", word);char *errmsg = NULL; int found = 0;int callback(void *data, int argc, char **argv, char **azColName) {if (argc > 0 && argv[0]) {strncpy(result, argv[0], result_size - 1);result[result_size - 1] = '\0';found = 1;}return 0;}if(sqlite3_exec(ppDb, sql, callback, NULL, &errmsg) != SQLITE_OK){printf("%d查询失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}if (!found) {strncpy(result, "未找到该单词", result_size - 1);result[result_size - 1] = '\0';}return 0;
}
int insert_account(sqlite3 *ppDb,char* account,int password)
{int flag=0;char sql[256] = ""; sprintf(sql,"insert into ACCOUNT_PASSWORD values(\"%s\",%d,%d);",account,password,flag);char *errmsg = NULL; if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d插入失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}return 0;
}
int empty_account(sqlite3 *ppDb)
{char sql[128] = ""; sprintf(sql, "delete from ACCOUNT_PASSWORD;");char *errmsg = NULL; if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d插入失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}return 0;
}
int enter_account(sqlite3 *ppDb,char* account,int password)
{char sql1[256] = ""; sprintf(sql1,"select * from ACCOUNT_PASSWORD where account==\"%s\" and password==%d and flag==0;",account,password);char *errmsg = NULL; if(sqlite3_exec(ppDb, sql1, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d查询失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}char sql[256] = ""; sprintf(sql,"update ACCOUNT_PASSWORD set flag=1 where account==\"%s\" and password==%d;",account,password);if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d修改失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}return 0;}
int break_account(sqlite3 *ppDb,char* account,int password)
{char sql1[256] = ""; sprintf(sql1,"select * from ACCOUNT_PASSWORD where account==\"%s\" and password==%d and flag==1;",account,password);char *errmsg = NULL; if(sqlite3_exec(ppDb, sql1, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d查询失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}char sql[256] = ""; sprintf(sql,"update ACCOUNT_PASSWORD set flag=0 where account==\"%s\" and password==%d;",account,password);if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("%d修改失败:%s\n",__LINE__, errmsg);sqlite3_free(errmsg);return -1;}return 0;}
void handle_client(int new_fd,struct sockaddr_in cin,sqlite3 *ppDb)
{printf("[%s:%d]发来连接,new_fd = %d\n", inet_ntoa(cin.sin_addr),ntohs(cin.sin_port) ,new_fd);acc_pass p=(acc_pass)malloc(sizeof(struct acc_pass));search_query_t query;int flag;char result[4096];char current_account[20]={};while(1){memset(p,0,sizeof(struct acc_pass));int res=recv(new_fd,p,sizeof(struct acc_pass),0);if(res<=0){if(res==0){printf("客户端[%s:%d]已下线\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));if(strlen(current_account)>0){break_account(ppDb,current_account,p->password);}}else{perror("recv error");}break;}printf("收到客户端[%s:%d]请求: num=%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), p->num);switch(p->num){case 1:printf("注册账号:%s,%d\n",p->account,p->password);flag=insert_account(ppDb,p->account,p->password);break;case 2:printf("登录账户:%s, %d\n",p->account,p->password);flag=enter_account(ppDb,p->account,p->password);if(flag==0){strcpy(current_account,p->account);}send(new_fd,&flag,sizeof(flag),0);break;case 3:printf("退出账户:%s, %d\n",p->account,p->password);flag=break_account(ppDb,p->account,p->password);if(flag==0){memset(current_account,0,sizeof(current_account));}send(new_fd,&flag,sizeof(flag),0);break;case 4: printf("查询单词请求\n");if (strlen(current_account) == 0) {strcpy(result, "请先登录");send(new_fd, result, strlen(result) + 1, 0);break;}memset(&query, 0, sizeof(query));recv(new_fd, &query, sizeof(query), 0);printf("查询单词: %s\n", query.word);memset(result, 0, sizeof(result));if(query_word(ppDb, query.word, result, sizeof(result)) == 0){send(new_fd, result, strlen(result) + 1, 0);printf("查询结果: %s -> %s\n", query.word, result);record_search_history(ppDb,p->account,p->password , current_account, query.word, result);}else{send(new_fd, "查询失败", 9, 0);}break;default:printf("未知请求:%d\n",p->num);break;}}free(p);close(new_fd);printf("[%s:%d]链接处理结束,new_fd = %d\n", inet_ntoa(cin.sin_addr),ntohs(cin.sin_port) ,new_fd);}
int main(int argc, const char *argv[])
{int fd=open("./dict.txt",O_RDONLY);if(fd==-1){ERR_MSG("open error");}sqlite3 *ppDb=NULL;if(sqlite3_open("./dict.db",&ppDb)!=SQLITE_OK){printf("sqlite3_open error errcode=%d, errmsg=%s\n",sqlite3_errcode(ppDb), sqlite3_errmsg(ppDb));return -1;}char *sql = "create table if not exists WORD_TRANSLATE(word char,translate char);";char *errmsg = NULL; if(sqlite3_exec(ppDb, sql, NULL, NULL, &errmsg) != SQLITE_OK){printf("数据表创建失败:%s\n", errmsg);sqlite3_free(errmsg); return -1;}empty_word(ppDb); char *sql1 = "create table if not exists ACCOUNT_PASSWORD(account char,password int,flag int);";if(sqlite3_exec(ppDb, sql1, NULL, NULL, &errmsg) != SQLITE_OK){printf("数据表创建失败:%s\n", errmsg);sqlite3_free(errmsg); return -1;}empty_account(ppDb);char buf1[128];char buf2[128];char buf[1]={};size_t set=0;off_t set1,set2;set1=lseek(fd,0,SEEK_END);lseek(fd,0,SEEK_SET);while(1){memset(buf1,0,sizeof(buf1));memset(buf2,0,sizeof(buf2));memset(buf,0,sizeof(buf));for(int i=0;i<128&&buf[0]!=' '&&buf[0]!='\n';i++){set=read(fd,buf,sizeof(buf));buf1[i]=buf[0];if(set==0){break;}}buf1[strcspn(buf1," ")]='\0';while(buf[0]==' '){set=read(fd,buf,sizeof(buf));}lseek(fd,-1,SEEK_CUR);printf("work=%s",buf1);for(int i=0;i<128&&buf[0]!='\n';i++){set=read(fd,buf,sizeof(buf));buf2[i]=buf[0];set2=lseek(fd,0,SEEK_CUR);if(set==0){break;}}buf2[strcspn(buf2,"\n")]='\0';printf("buf2=%s\n",buf2);insert_word(ppDb,buf1,buf2);if(set1==set2){break;}}close(fd);int sfd = socket(AF_INET, SOCK_STREAM, 0);if(-1 == sfd){perror("socket error");return -1;}printf("socket 成功 sfd = %d\n", sfd);int reuse = 1;if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1){perror("setsockopt error");return -1;}printf("端口号快速重用成功\n");struct sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(SER_PORT); sin.sin_addr.s_addr = inet_addr(SER_IP); if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) ==-1){perror("bind error");return -1;}printf("bind success\n");if(listen(sfd, 128) == -1){perror("listen error");return -1;}printf("listen success\n");struct sockaddr_in cin; socklen_t addrlen = sizeof(cin); acc_pass p=(acc_pass)malloc(sizeof(struct acc_pass));while(1){int new_fd = accept(sfd, (struct sockaddr*)&cin, &addrlen);if(-1 == new_fd){perror("accept error");continue;}printf("[%s:%d]发来连接,new_fd = %d\n", inet_ntoa(cin.sin_addr),\ntohs(cin.sin_port) ,new_fd);pid_t pid=fork();if(pid==0){close(sfd);handle_client(new_fd,cin,ppDb);exit(EXIT_SUCCESS);}else if(pid>0){close(new_fd);}else{close(new_fd);ERR_MSG("fork error");}}sqlite3_close(ppDb);return 0;
}
2、客户端
#include <myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.116.128"
typedef struct acc_pass
{int num;char account[20];int password;
}*acc_pass;
typedef struct word_query
{int num;char word[50];
} word_query_t;
int do_add(int num,acc_pass p,int cfd)
{printf("输入账号:");scanf("%s",p->account);printf("输入密码:");scanf("%d",&p->password);p->num=num;send(cfd, p, sizeof(struct acc_pass), 0);printf("发送成功\n");
}
int do_register(int num,acc_pass p,int cfd)
{printf("输入账号:");scanf("%s",p->account);printf("输入密码:");scanf("%d",&p->password);p->num=num; send(cfd, p, sizeof(struct acc_pass), 0);printf("发送成功\n");}
int do_search_word(int cfd)
{word_query_t query;query.num = 4; printf("请输入要查询的单词:");scanf("%s", query.word);send(cfd, &query, sizeof(query), 0);char result[256];recv(cfd, result, sizeof(result), 0);printf("查询结果: %s\n", result);return 0;
}
int main(int argc, const char *argv[])
{int cfd = socket(AF_INET, SOCK_STREAM, 0);if(-1 == cfd){perror("socket error");return -1;}printf("socket success cfd = %d\n", cfd);struct sockaddr_in sin;sin.sin_family = AF_INET; sin.sin_port = htons(SER_PORT); sin.sin_addr.s_addr = inet_addr(SER_IP); if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){perror("connect error");return -1;}printf("连接成功\n");acc_pass p=(acc_pass)malloc(sizeof(struct acc_pass)); int num;while(1){printf("1、注册账户\n");printf("2、登录账号\n");printf("3、退出账户\n");printf("选择功能:");scanf("%d",&num);switch(num){case 1:do_add(num,p,cfd);break;case 2:do_register(num,p,cfd);{while(1){printf("1、查找单词\n");printf("2、查找历史记录\n");printf("3、返回上一级\n");printf("选择功能:");scanf("%d",&num);switch(num){case 1:do_search_word(cfd);break;case 2:break;case 3:break;}if(num==3){break;}}}break;case 3:break;}}close(cfd);return 0;
}