目录
- #ifndef __DICT_H__
- #define __DICT_H__
- #include
- #include
-
- #define SERIP "192.168.114.73"
- #define PORT 8888
-
- #define ERR_MSG(msg) do{\
- printf("%d: ",__LINE__);\
- perror(msg);\
- }while(0);
-
- /*服务器使用 */
- //词典数据库的初始化和导入
- int dict_init(sqlite3 *db);
-
- //TCP服务器搭建函数
- int TCP_ser_set(struct sockaddr_in* psin);
-
- //回收子进程函数
- void handler(int signum);
-
- //子进程中的操作
- void child_operate(int newfd, sqlite3 *db);
- /*服务器使用 */
-
- /*客户端使用 */
- //TCP客户端搭建函数
- int TCP_cli_set();
-
- //客户端中的操作
- void cli_operate(int cfd);
-
- /*客户端使用 */
- #endif
- #include
- #include
- #include "dict.h"
-
- int do_create(sqlite3 *db);
- int do_insert(sqlite3 *db, char * English, char *Chinese);
- int msg_get(FILE *fp, char*pEng, char *pChin);
- int do_init(sqlite3 *db);
- int usrname_not_reuse(sqlite3 *db, const char *usrname, const char *tablename);
-
- int dict_init(sqlite3 *db)
- {
-
- //初始化数据库中词典数据表
- do_init(db);
- printf("数据库初始化成功\n");
-
- //打开文件
- FILE *fp;
- char English[32] = "";
- char Chinese[64] = "";
- if(NULL == (fp=fopen("./dict.txt","r"))){
- printf("%d:",__LINE__);
- perror("fopen error");
- return -1;
- }
-
- //创建表格
- do_create(db);
-
- printf("词典数据导入中\n...\n");
- while(1){
- //从dict.txt中读取一行的数据
- bzero(English, sizeof(English));
- bzero(Chinese, sizeof(Chinese));
- msg_get(fp, English, Chinese);
- //将English和Chinese写入表格中
- do_insert(db, English, Chinese);
-
- //printf("%s\t%s\n",English, Chinese);
-
- if(feof(fp)){
- printf("导入成功\n");
- break;
- }
- }
-
-
- //关闭文件
- fclose(fp);
- return 0;
- }
-
- int msg_get(FILE *fp, char* pEng, char *pChin){
- char tmp = 0;
- int i = 0;
- while((tmp = fgetc(fp))!=' '){
- pEng[i] = tmp;
- i++;
- if(feof(fp)){
- return 0;
- }
- }
- i = 0;
- while(fgetc(fp)==' ');
- fseek(fp,-1,SEEK_CUR);
- while((tmp = fgetc(fp))!='\n'){
- pChin[i] = tmp;
- i++;
- if(feof(fp)){
- pChin[i-1] = 0;
- break;
- }
- }
- return 0;
- }
-
- int do_create(sqlite3 *db){
- if(db == NULL){
- printf("数据库不存在\n");
- return -1;
- }
-
- //创建词典数据表
- char sql[128] = "create table if not exists dict(ENGLISH char, TRANSLATION char);";
-
- char *errmsg = NULL;
- if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
- printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
- return -1;
- }
-
- //创建已注册用户数据表
- bzero(sql,sizeof(sql));
- strcpy(sql,"create table if not exists registeredUsr(id char primary key, passwd char);");
-
- if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
- printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
- return -1;
- }
- //创建已登录用户数据表
- bzero(sql,sizeof(sql));
- strcpy(sql,"create table if not exists loadedUsr(id char primary key, passwd char);");
-
- if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
- printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
- return -1;
- }
-
-
- //创建成功
- return 0;
- }
-
- int do_init(sqlite3 *db){
- if(db == NULL){
- printf("数据库不存在\n");
- return -1;
- }
-
- char sql[128] = "drop table dict;";
-
- char *errmsg = NULL;
- if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
- printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
- return -1;
- }
-
- //创建成功
- return 0;
- }
-
- //插入表格函数
- int do_insert(sqlite3 *db, char * English, char *Chinese){
- if(db == NULL){
- printf("数据库不存在\n");
- return -1;
- }
-
- char sql[128] = "";
- snprintf(sql, sizeof(sql),"insert into dict values(\"%s\", \"%s\");",English, Chinese);
-
- char *errmsg = NULL;
- if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
- printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
- return -1;
- }
-
- return 0;
- }
-
- //TCP服务器搭建函数
- int TCP_ser_set(struct sockaddr_in* psin){
- int sfd;
- if((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
- ERR_MSG("socket error");
- return -1;
- }
-
- int optval = 1;
- //允许端口快速复用
- if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))<0){
- ERR_MSG("setsockopt error");
- return -1;
- }
-
- //获取地址信息结构体
- struct sockaddr_in sin;
- sin.sin_family = AF_INET;
- sin.sin_port = htons(PORT);
- sin.sin_addr.s_addr = inet_addr(SERIP);
- * psin = sin;
- //绑定
- if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin))<0){
- ERR_MSG("bind error");
- return -1;
- }
-
- //设为监听
- if(listen(sfd,128)<0){
- ERR_MSG("listen error");
- return -1;
- }
-
- printf("服务器搭建成功\n");
- return sfd;
- }
-
- //回收子进程函数
- void handler(int signum){
- while(waitpid(-1,NULL,WNOHANG)!=0);
- }
-
- //子进程中的操作
- void child_operate(int newfd, sqlite3 *db){
- //判断传入的newfd是否合法
- if(newfd<0){
- printf("连接失败\n");
- return;
- }
- char buf[150] = " ";
- //用于读取数据包中的操作码
- unsigned short *operatorPtr = (unsigned short*)buf;
- //用于登录后记录用户名,便于读写对应用户的历史记录数据库
- char usrname[20] = " ";
- //用于读取数据包中的用户名
- char *usrnamePtr = buf + 2;
- //需要后续计算得到数据包中数据的位置
- char *dataPtr = NULL;
- //获取用户名的长度
- int usrnameLen = 0;
- //定义一个变量接收返回值
- int res = 0;
- //保存命令的数组
- char sql[128] = " ";
- while(1){
- bzero(buf,sizeof(buf));
- //接收
- if(recv(newfd, buf, sizeof(buf), 0) == -1){
- ERR_MSG("recv error");
- break;
- }
- //获取的是用户名的长度
- usrnameLen = strlen(usrnamePtr);
- //可知数据包中数据的位置为
- dataPtr = usrnamePtr + usrnameLen + 1;
- //printf("%s\n",buf);
- //send(newfd,buf,sizeof(buf),0);
- //注册
- if(1 == *operatorPtr){
- //现在,usrnamePtr指向用户名,dataPtr是数据的起头,在注册里面,数据包应该保存用户对应的密码
- //检索已注册用户数据表,看看用户名是否存在
- res = usrname_not_reuse(db, usrnamePtr, "registeredUsr");
-
- if(-1 == res){
- //说明这个函数调用遇到问题
- //组一个返回包
- *operatorPtr = 7;
- strcpy(dataPtr,"there is something wrong");
- }else if(0 == res){
- //说明用户名已存在
- *operatorPtr = 7;
- strcpy(dataPtr,"用户名已存在");
- }else if(1 == res){
- //说明用户名不在数据库中,可以进行注册
- bzero(sql, sizeof(sql));
-
- snprintf(sql, sizeof(sql),"insert into registeredUsr values(\"%s\", \"%s\");",usrnamePtr, dataPtr);
-
- char *errmsg = NULL;
- if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
- printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
- break;
- }
-
- *operatorPtr = 7;
- strcpy(dataPtr,"注册成功");
-
- }
-
- }else if(2 == *operatorPtr){
- //登录
- //现在,usrnamePtr指向用户名,dataPtr是数据的起头,在登录里面,数据包应该保存用户对应的密码
- //检索已登录用户数据表,看看用户名是否存在
- res = usrname_not_reuse(db, usrnamePtr, "registeredUsr");
- if(-1 == res){
- //说明这个函数调用遇到问题
- //组一个返回包
- *operatorPtr = 7;
- strcpy(dataPtr,"there is something wrong");
- }else if(1 == res){
- //说明在已注册表中未找到该用户,说明该账号还没被注册
- *operatorPtr = 7;
- strcpy(dataPtr,"该账号还未被注册,请先注册");
- }else if(0 == res){
- //说明在已注册表中找到了该用户,进行下一步登录操作
- res = usrname_not_reuse(db, usrnamePtr, "loadedUsr");
- if(-1 == res){
- //说明这个函数调用遇到问题
- //组一个返回包
- *operatorPtr = 7;
- strcpy(dataPtr,"there is something wrong");
- }else if(0 == res){
- //说明用户名已存在已登录数据表,说明用户已经登录
- *operatorPtr = 7;
- strcpy(dataPtr,"该账号已登录,请检查账号是否被盗用");
- }else if(1 == res){
- //说明该用户已注册且未登录,可以进行登录
- bzero(sql, sizeof(sql));
-
- char **result = NULL;
- int row = 0;
- int col = 0;
- char *errmsg = NULL;
- int flag = 0;
-
- snprintf(sql,sizeof(sql),"select id,passwd from registeredUsr;");
-
- if((res = sqlite3_get_table(db, sql, &result, &row, &col, &errmsg))!=0){
- printf("%d:sqlite3_get_table error\n",__LINE__);
- printf("%s\n",strerror(res));
- break;
- }
-
- //遍历比较,第0行是项的名,所以从第一行开始
- for(int i=col; i<=row*col; i+=col){
- if(strcmp(*(result+i),usrnamePtr) == 0&&strcmp(*(result+i+1),dataPtr) == 0){
- //登录成功后要将用户数据写入已登录用户数据表
- bzero(sql, sizeof(sql));
-
- snprintf(sql, sizeof(sql),"insert into loadedUsr values(\"%s\", \"%s\");",usrnamePtr, dataPtr);
-
- char *errmsg = NULL;
- if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
- printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
- break;
- }
- //满足条件说明用户密码匹配成功,即登录成功
- *operatorPtr = 7;
- strcpy(dataPtr,"登录成功");
- //将登录成功的用户名保存
- strcpy(usrname,usrnamePtr);
- flag = 0;
-
- //然后应该新建一个对应用户的历史记录数据表
- bzero(sql, sizeof(sql));
- snprintf(sql, sizeof(sql),"create table if not exists %shis(ENGLISH char , TRANSLATION char, current timestamp default current_timestamp);",usrname);
- if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
- printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
- break;
- }
-
- break;
- }else{
- flag = 1;
- }
- }
-
- if(1 == flag){
- *operatorPtr = 7;
- strcpy(dataPtr,"密码错误");
- }
-
- }
- }
-
- }else if(3 == *operatorPtr){
- //退出
- //先判断该进程中usrname字符串内是否有内容,如果有的话,说明用户是异常退出,先帮用户
- //退出登录,再进行退出操作
- if(usrname[0]!=0){
- //usrname字符串的第一个元素不为0,说明非空,检查usrname字符串内容是否在
- //已登录用户信息数据表中
- res = usrname_not_reuse(db, usrname, "loadedUsr");
- if(0 == res){
- //说明用户还在已登录用户信息表中,说明用户确实是异常退出,先退出登录
- //从已登录用户数据表中,将用户名对应的项删除
- bzero(sql, sizeof(sql));
- char *errmsg = NULL;
- snprintf(sql,sizeof(sql),"delete from loadedUsr where id=\'%s\';",usrname);
-
- if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
- printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
- break;
- }
- //将usrname这个字符串清空
- bzero(usrname,sizeof(usrname));
-
- }else if(1 == res){
- //说明用户已经退出登录
- bzero(usrname,sizeof(usrname));
- }
- }
-
- //结束函数
- return;
-
- }else if(4 == *operatorPtr){
- //查询
- //接收到要查询的英文单词,需要在dict数据表中查找,没找到的话也应该返回一个数据提示
- bzero(sql, sizeof(sql));
-
- char **result = NULL;
- int row = 0;
- int col = 0;
- char *errmsg = NULL;
- int flag = 0;
-
- snprintf(sql,sizeof(sql),"select ENGLISH,TRANSLATION from dict where ENGLISH=\'%s\';",dataPtr);
-
- if((res = sqlite3_get_table(db, sql, &result, &row, &col, &errmsg))!=0){
- printf("%d:sqlite3_get_table error\n",__LINE__);
- printf("%s\n",strerror(res));
- break;
- }
-
- *operatorPtr = 7;
- if(strcmp(*(result+2),dataPtr)==0){
- //如果查找到的因为原型与发送来的相同,说明要找的单词存在
- snprintf(dataPtr,128,"%s\t%s",*(result+2),*(result+3));
-
- //将对应的英文及其翻译还有当时时间记录
- bzero(sql, sizeof(sql));
-
- snprintf(sql, sizeof(sql),"insert into %shis values(\"%s\", \"%s\",CURRENT_TIMESTAMP);",usrname, *(result+2), *(result+3));
-
- if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
- printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
- break;
- }
-
- }else{
- //否则不存在,发送一个反馈的包
- strcpy(dataPtr,"抱歉该单词还未收录");
- }
-
-
- }else if(5 == *operatorPtr){
- //历史记录
- bzero(sql, sizeof(sql));
-
- char **result = NULL;
- int row = 0;
- int col = 0;
- char *errmsg = NULL;
- int flag = 0;
-
- bzero(sql, sizeof(sql));
-
- snprintf(sql,sizeof(sql),"select * from %shis;",usrname);
- //printf("%s\n",sql);
-
- if((res = sqlite3_get_table(db, sql, &result, &row, &col, &errmsg))!=0){
- printf("%d:sqlite3_get_table error\n",__LINE__);
- printf("%s\n",strerror(res));
- break;
- }
-
- *operatorPtr = 7;
- for(int i=col; i<=row*col; i+=col){
- *operatorPtr = 7;
- snprintf(dataPtr,128,"%s\t%s\t%s",*(result+i),*(result+i+1),*(result+i+2));
- //发送返回的数据包
- send(newfd, buf, sizeof(buf), 0);
- bzero(dataPtr,128);
- }
- }else if(6 == *operatorPtr){
- //退出登录
- //从已登录用户数据表中,将用户名对应的项删除
- bzero(sql, sizeof(sql));
- char *errmsg = NULL;
- snprintf(sql,sizeof(sql),"delete from loadedUsr where id=\'%s\';",usrname);
-
- if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK){
- printf("%d:sqlite3_exec error %s\n",__LINE__, sqlite3_errmsg(db));
- break;
- }
- //将usrname这个字符串清空
- bzero(usrname,sizeof(usrname));
- *operatorPtr = 7;
- strcpy(dataPtr,"账号成功退出登录");
- }else{
- }
- //发送返回的数据包
- send(newfd, buf, sizeof(buf), 0);
- }
-
- }
-
- //查询用户名是否重复函数
- int usrname_not_reuse(sqlite3 *db, const char *usrname, const char *tablename){
- char **res = NULL;
- int row = 0;
- int col = 0;
- char *errmsg = NULL;
-
- //调用查询函数
- char sql[128] = " ";
- snprintf(sql,sizeof(sql),"select id from %s;",tablename);
-
- if(sqlite3_get_table(db, sql, &res, &row, &col, &errmsg)!=0){
- printf("%d:sqlite3_get_table error\n",__LINE__);
- return -1;
- }
-
- //遍历比较,第0行是项的名,所以从1开始
- for(int i=1; i<=row; i++){
- if(strcmp(*(res+i),usrname) == 0){
- //满足条件说明用户名已存在,返回0
- return 0;
- }
- }
-
- //遍历到结束,说明该用户名还未存在,返回1
- return 1;
- }
-
- //TCP客户端搭建函数
- int TCP_cli_set(){
- int cfd;
- if((cfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
- ERR_MSG("socket error");
- return -1;
- }
-
- int optval = 1;
- //允许端口快速复用
- if(setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))<0){
- ERR_MSG("setsockopt error");
- return -1;
- }
-
- //获取地址信息结构体
- struct sockaddr_in sin;
- sin.sin_family = AF_INET;
- sin.sin_port = htons(PORT);
- sin.sin_addr.s_addr = inet_addr(SERIP);
-
- //连接
- if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin))<0){
- ERR_MSG("connect error");
- return -1;
- }
-
- printf("客户端搭建成功\n");
- return cfd;
- }
-
- //客户端中的操作
- void cli_operate(int cfd){
- if(cfd<0){
- printf("文件描述符有误\n");
- return;
- }
- //菜单
- int opt = 0;
- char buf[150] = " ";
- unsigned short *operatorPtr = (unsigned short *)buf;
- //记录用户名
- char id[20] = " ";
- //记录用户名长度
- int idlen = 0;
- //记录已登录用户的用户名
- char loadedid[20] = " ";
- int loadedidlen = 0;
- //记录密码
- char passwd[20] = " ";
- //记录密码长度
- int passwdlen = 0;
- while(1){
- bzero(buf,sizeof(buf));
- bzero(id,sizeof(id));
- bzero(passwd,sizeof(passwd));
-
- system("clear");
- printf("****************************\n");
- printf("**********电子词典**********\n");
- printf("***********1.注册***********\n");
- printf("***********2.登录***********\n");
- printf("***********3.退出***********\n");
- printf("****************************\n");
- printf("请输入>>");
- scanf("%d",&opt);
-
- if(1 == opt){
- //注册
- *operatorPtr = 1;
- printf("请输入要注册的用户名:");
- while(1){
- scanf("%s",id);
- while(getchar()!=10);
- //记录账号长度,保证长度符合要求才能跳出循环
- idlen = strlen(id);
- if(idlen>0&&idlen<20){
- break;
- }
- printf("账号长度请不要超过20,请重新输入:");
- }
- printf("请输入密码:");
- while(1){
- scanf("%s",passwd);
- while(getchar()!=10);
- //记录密码长度,保证长度符合要求才能跳出循环
- passwdlen = strlen(passwd);
- if(passwdlen<20&&passwdlen>0){
- break;
- }
- printf("密码长度请不要超过20,请重新输入:");
- }
- //将账号写到对应位置
- strcpy(buf+2,id);
- //将密码写到对应位置
- strcpy(buf+3+idlen,passwd);
-
- send(cfd, buf, sizeof(buf), 0);
- recv(cfd, buf, sizeof(buf), 0);
- printf("%s\n",buf+3+idlen);
-
- }else if(2 == opt){
- //登录
- *operatorPtr = 2;
- printf("请输入要登录的用户名:");
- while(1){
- scanf("%s",id);
- while(getchar()!=10);
- //记录账号长度,保证长度符合要求才能跳出循环
- idlen = strlen(id);
- if(idlen>0&&idlen<20){
- break;
- }
- printf("账号长度请不要超过20,请重新输入:");
- }
- printf("请输入密码:");
- while(1){
- scanf("%s",passwd);
- while(getchar()!=10);
- //记录密码长度,保证长度符合要求才能跳出循环
- passwdlen = strlen(passwd);
- if(passwdlen<20&&passwdlen>0){
- break;
- }
- printf("密码长度请不要超过20,请重新输入:");
- }
- //将账号写到对应位置
- strcpy(buf+2,id);
- //将密码写到对应位置
- strcpy(buf+3+idlen,passwd);
-
- send(cfd, buf, sizeof(buf), 0);
- recv(cfd, buf, sizeof(buf), 0);
- printf("%s\n",buf+3+idlen);
- if(strcmp(buf+3+idlen,"登录成功")==0){
- strcpy(loadedid,id);
- loadedidlen = idlen;
- //将账号写到对应位置
- strcpy(buf+2,loadedid);
-
- printf("输入任意字符刷新>>");
- getchar();
- while(getchar()!=10);
-
- while(1){
- strcpy(buf+2,loadedid);
- system("clear");
- printf("****************************\n");
- printf("**********电子词典**********\n");
- printf("*****usr:%s*****\n",loadedid);
- printf("***********1.查询***********\n");
- printf("*********2.历史记录*********\n");
- printf("*********3.退出登录*********\n");
- printf("****************************\n");
- printf("请输入>>");
- scanf("%d",&opt);
-
- if(1 == opt){
- //查找
- *operatorPtr = 4;
- printf("请输入要查找的单词>>");
- scanf("%s",buf+3+loadedidlen);
-
- send(cfd, buf, sizeof(buf), 0);
- recv(cfd, buf, sizeof(buf), 0);
- printf("%s\n",buf+3+loadedidlen);
- }else if(2 == opt){
- //历史记录
- *operatorPtr = 5;
- //由于已经将用户id写入buf包中,只需将包发送即可
- send(cfd, buf, sizeof(buf), 0);
- recv(cfd, buf, sizeof(buf), 0);
- char *dataPtr = buf+3+loadedidlen;
- //应该循环接收,那么服务器发包应该在数据区写入结束标志
- while(*dataPtr){
- printf("%s\n",dataPtr);
- recv(cfd, buf, sizeof(buf), 0);
- }
- }else if(3 == opt){
- //退出登录
- //发送一个操作码为6的空包,向服务器提示该账号要退出登录
- //将记录已登录id的字符串清空,用于存储下一个登录用户id
- *operatorPtr = 6;
- send(cfd, buf, sizeof(buf), 0);
-
- recv(cfd, buf, sizeof(buf), 0);
- printf("%s\n",buf+3+loadedidlen);
-
- bzero(loadedid,sizeof(loadedid));
- loadedidlen = 0;
- break;
- }else{
- printf("输入不规范,亲人两行泪,请重新输入\n");
- }
-
- printf("输入任意字符刷新>>");
- getchar();
- while(getchar()!=10);
- bzero(buf,sizeof(buf));
- }
- }
- }else if(3 == opt){
- //退出
- //发送一个操作码为3的空包
- *operatorPtr = 3;
- send(cfd, buf, sizeof(buf), 0);
- break;
- }else{
- printf("输入不规范,亲人两行泪,请重新输入\n");
- }
-
- printf("输入任意字符刷新>>");
- getchar();
- while(getchar()!=10);
- }
-
-
-
- }
- #include
- #include
- #include "dict.h"
-
- int main(int argc, const char *argv[])
- {
- //回收子进程
- signal(SIGCHLD,handler);
-
- //打开数据库
- sqlite3 * db;
- if(sqlite3_open("./dict.db", &db) != SQLITE_OK){
- printf("%d:sqlite3_open error %s\n",__LINE__, sqlite3_errmsg(db));
- return -1;
- }
-
- //初始化数据库,完成词典数据表的重载以及用户信息数据库的导入
- dict_init(db);
-
- struct sockaddr_in sin;
- socklen_t addrlen = sizeof(sin);
- int sfd;
- if((sfd = TCP_ser_set(&sin))<0){
- printf("服务器搭建失败");
- return -1;
- }
-
- pid_t pid;
- int newfd;
- while(1){
- if((newfd = accept(sfd, (struct sockaddr*)&sin, &addrlen))<0){
- ERR_MSG("accept error");
- return 0;
- }
-
- pid = fork();
- if(pid == 0){
- close(sfd);
-
- printf("这是子进程\n");
- child_operate(newfd, db);
-
- close(newfd);
- //关闭数据库
- if(sqlite3_close(db) != SQLITE_OK){
- printf("%d:sqlite3_close error %s\n",__LINE__, sqlite3_errmsg(db));
- return -1;
- }
- exit(EXIT_SUCCESS);
- }
- close(newfd);
-
- }
-
-
- //关闭数据库
- if(sqlite3_close(db) != SQLITE_OK){
- printf("%d:sqlite3_close error %s\n",__LINE__, sqlite3_errmsg(db));
- return -1;
- }
- close(sfd);
- return 0;
- }
- #include
- #include
- #include "dict.h"
-
- int cfd;
-
- //用户按下ctrl+c后给服务器发一个退出登录的包
- void handlerINT(int signum){
- char buf[150] = " ";
- unsigned short *operatorPtr = (unsigned short*)buf;
- //发送一个操作码为3的空包,向服务器提示该账号要退出,退出功能中包含了退出登录
- *operatorPtr = 3;
- send(cfd, buf, sizeof(buf), 0);
- }
-
- int main(int argc, const char *argv[])
- {
- //用户按下ctrl+c后给服务器发一个退出登录的包
- signal(2,handlerINT);
-
- //调用TCP客户端搭建函数
- if((cfd = TCP_cli_set())<0){
- printf("客户端搭建失败\n");
- }
-
- cli_operate(cfd);
-
-
- close(cfd);
- return 0;
- }