你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

2021-11-13

2021-11-13 10:20:57

在线词典

功能:基于Linux操作系统,网络编程和数据库实现在线词典

客户端可以注册,登入,查询历史信息等操作,使用基于TCP的多线程并发服务器,并使用sqlite3数据库实现单词的导入以及对用户信息的管理。

1.注册:若用户名已经注册过,重新注册

2.登录:用户名或密码错误需重新登录

3.查询:输入要查的单词,#键结束查询

4.历史:可以查询当前用户历史查找过的单词

5.退出:退出在线词典

客户端相关代码

客户端主函数相关代码

#include "./inc/dict_socket.h"

void mainloop(int sfd);

int main(int argc, const char *argv[])
{
   //判断参数是否正确
    if(argc < 3)
    {   
        printf("参数不正确 请按以下格式输入 ip port\n");                       
        ERR_MSG();
        return -1; 
    }   
    struct sockaddr_in sin;    
    struct sockaddr_in cin;
    char name[32] = ""; 
    int op; 

    int sfd = init_socket(argv[1], atoi(argv[2]), &sin);

    mainloop(sfd);

    return 0;
}                                                                                                                                                                                                             

#if 0
    1:注册
    2:登录
    3:退出
#endif

void mainloop(int sfd)
{
    int op = 0;
    char name[32] = ""; 
    int flag = 0;
    system("clear");
    menu1();
    while(1)
    {   
        scanf("%d", &op);
        clear();
        switch(op)
        {
        case 1:
                    if(flag == 0)
            {
                do_register(sfd);
                menu2();
            }
            break;                                                                                                                                                                                            
        case 2:
            if(flag == 0)
            {
                if(do_login(sfd, name) == 0)
                {
                    flag = 1;
                    menu3();
                }
                else
                {
                    menu2();
                }
            }
            break;
        case 3:
            if(flag == 1)
            {
                do_quit(sfd,name);
                menu2();
                flag = 0;
            }
            break;
        case 4:
            if(flag == 1)
            {
                do_search(sfd,name);
                menu3();
            }
            break;
        case 5:
            if(flag == 1)
            {
                do_history(sfd,name);
                menu3();
            }
            break;
        case 0:
            if(flag == 0)
            {
                return ;
            }
            break;
        default:
            break;
        }
    }

}

客户端网络相关代码


#include "../inc/dict_socket.h"

int init_socket(const char* ip, short port, struct sockaddr_in* sin)
{
    //创建流式套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(sfd < 0)
    {   
        perror("socket");
        ERR_MSG();
        return -1; 
    }   

    //允许端口快速重用
    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {   
        perror("setsockopt");
        ERR_MSG();
        return -1; 
    }   


    //填充地址信息结构体 非必须绑定
    sin->sin_family = AF_INET;
    sin->sin_port = htons(port);
    sin->sin_addr.s_addr  = inet_addr(ip);                                                                                                                                                                    

    if(connect(sfd, (struct sockaddr *)sin, sizeof(struct sockaddr_in)) < 0)
    {   
        perror("connect");
        ERR_MSG();
        return -1; 
    }   
    printf("网络初始化成功\n");
    printf("连接成功\n");
    return sfd;
}

客户端操作代码

#include "../inc/op.h"

void menu1()
{
    printf("\t\t****************\n");
    printf("\t\t****************\n");
    printf("\t\t***  1 注册  ***\n");
    printf("\t\t***  2 登录  ***\n");
    printf("\t\t***  0 退出  ***\n");
    printf("\t\t****************\n");
    printf("\t\t****************\n");
}

void menu2()
{
    printf("输入任意字符清屏>>");
    while(getchar()!=10);
    system("clear");
    menu1();
}
void menu3()
{
    printf("输入任意字符清屏>>");
    while(getchar()!=10);
    system("clear");
    printf("\t\t****************\n");
    printf("\t\t****************\n");
    printf("\t\t***  3 退出  ***\n");
    printf("\t\t***  4 查询  ***\n");
    printf("\t\t***  5 历史  ***\n");
    printf("\t\t****************\n");
    printf("\t\t****************\n");


}

int do_register(int sfd)
{
    package pack;
    char buf[8] = ""; 
    pack.type = 'R';
    printf("请输入用户名:");
    fgets(pack.name, sizeof(pack.name), stdin);
    pack.name[strlen(pack.name) - 1] = 0;

    printf("请输入密码");
    fgets(pack.passwd, sizeof(pack.passwd), stdin);
    pack.passwd[strlen(pack.passwd) - 1] = 0;

    if(send(sfd, &pack, sizeof(pack), 0) < 0)
    {   
        perror("send");
        ERR_MSG();
        return -1; 
    }   
//  printf("发送成功\n");
    if(recv(sfd, buf, sizeof(buf), 0) < 0)
    {   
        ERR_MSG();
        perror("recv");
        return -1; 
    }   
    if(strncmp(buf, "success", 5) == 0)
    {   
        printf("注册成功\n");
    }   
    else if(strncmp(buf, "exist", 4) == 0)
    {   
        printf("用户名已存在,注册失败\n");
    }   
    else
    {   
        printf("recv buf: %s\n", buf);
    }   

    return 0;
}

int do_login(int sfd, char* name)
{
    package pack;
    char buf[8] = ""; 
    pack.type = 'L';
    printf("请输入用户名:");
    fgets(pack.name, sizeof(pack.name), stdin);
    pack.name[strlen(pack.name) - 1] = 0;

    printf("请输入密码:");
    fgets(pack.passwd, sizeof(pack.passwd), stdin);
    pack.passwd[strlen(pack.passwd) - 1] = 0;

    if(send(sfd, &pack, sizeof(pack), 0) < 0)
    {   
        perror("send");
        ERR_MSG();
        return -1; 
    }   
    //printf("发送成功\n");
    if(recv(sfd, buf, sizeof(buf), 0) < 0)
    {   
        perror("recv");
        ERR_MSG();
        return -1; 
    }   

    if(strncmp(buf, "notname", 7) == 0)
    {   
        printf("用户名不存在\n");
        return -1; 
    }   
    else if(strncmp(buf, "notwd", 5) == 0)
    {   
        printf("密码错误\n");
        return -1; 
    }   
    else if(strncmp(buf, "chongfu", 7) == 0)
    {   
        printf("重复登录\n");
        return -1; 
    }   
    else if(strncmp(buf, "success", 6) == 0)
    {   
        strcpy(name, pack.name);
        printf("登陆成功\n");
        return 0;
    }   
    else
    {   
        printf("recv : %s\n", buf);
    }   


    return 0;
}

int do_quit(int sfd, const char* name)
{
    package pack;
    pack.type = 'Q';
    strcpy(pack.name , name);
    strcpy(pack.passwd , "1");

    if(send(sfd, &pack, sizeof(pack), 0) < 0)
    {   
        perror("send");
        ERR_MSG();
        return -1; 
    }   
    //printf("发送成功\n");

    return 0;

}

int do_search(int sfd, const char* name)
{
    package pack;
    char world[128];
    char chinese[128] = ""; 
    pack.type = 'S';
    int row = 0;
    strcpy(pack.name , name);
    strcpy(pack.passwd , "1");
    if(send(sfd, &pack, sizeof(pack), 0) < 0)
    {   
        perror("send");
        ERR_MSG();
        return -1; 
    }   
    //printf("发送搜索请求成功\n");
    printf("请输入要查找的单词:");
    fgets(world, sizeof(world), stdin);
    if(send(sfd, world, sizeof(world), 0) < 0)                  
    {   
        perror("send");
        ERR_MSG();
        return -1; 
    }   
    //printf("send ----%s----\n", world);
    if(recv(sfd, &row, sizeof(row), 0) < 0)
    {   
        perror("recv");
        ERR_MSG();
        return -1; 
    }   
    //printf("recv from : %d\n", row);
    int i = 0;
    for(i=0; i<row; i++)
    {   
        if(recv(sfd, &chinese, sizeof(chinese), 0) < 0)
        {
            perror("recv");
            ERR_MSG();
            return -1; 
        }
        printf("%s\n", chinese);
    }   

}

int do_history(int sfd, const char* name)
{
    int row;
    int i = 0;
    char sndbuf[256];
    package pack;
    pack.type = 'H';
    strcpy(pack.name , name);
    strcpy(pack.passwd , "1");
    if(send(sfd, &pack, sizeof(pack), 0) < 0)
    {   
        perror("send");
        ERR_MSG();
        return -1; 
    }   
    if(recv(sfd, &row, sizeof(row), 0) < 0)
    {   
        perror("recv");
        ERR_MSG();
        return -1; 
    }   
    //printf("row = %d\n", row);

    for(i=1; i<row+1; i++)
    {   
        if(recv(sfd, &sndbuf, sizeof(sndbuf), 0) < 0)
        {
            perror("recv");
            ERR_MSG();
            return -1; 
        }
        printf("%s\b\n", sndbuf);
    }   
}
        

服务器相关代码

主函数部分

#include "./inc/sqlite.h"
#include "./inc/dict_socket.h"
#include "./inc/op.h"

void* callback(void* arg);

typedef struct
{
    int newfd;
    struct sockaddr_in cin;
    sqlite3* db;
}Msg;

int main(int argc, const char *argv[])
{
    //判断参数是否正确
    if(argc < 3)
    {
        printf("参数不正确 请按以下格式输入 ip port\n");
        ERR_MSG();
        return -1;
    }
    //数据库初始化
    sqlite3 *db;
    db = init_dict_sqlite(db);

    int newfd = 0;
    struct sockaddr_in sin;
    struct sockaddr_in cin;
    socklen_t addrlen = sizeof(struct sockaddr_in);
    Msg msg;

    //网络初始化
    int sfd = init_socket(argv[1], atoi(argv[2]), &sin);

    //创建多线程并发服务器
    pthread_t pid;
    while(1)
    {
        if((newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen)) < 0)
        {
            perror("accept");
            ERR_MSG();
            return -1;
        }
        msg.newfd = newfd;
        msg.cin = cin;
        msg.db = db;
        //连接成功
        printf("[%s %d %d] 已连接\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);
        //创建线程
        if(pthread_create(&pid, NULL, callback, &msg) < 0)
        {
            perror("pthread_create");
            ERR_MSG();
            return -1;
        }
    }

    close(sfd);
    return 0;
}

void* callback(void* arg)
{
    pthread_detach(pthread_self());
    package pack;
    Msg* msg = (Msg*)arg;
    int newfd = msg->newfd;
    sqlite3* db = msg->db;
    struct sockaddr_in cin = msg->cin;
    int rett = -1;
    while(1)
    {
        if((rett = recv(newfd, &pack, sizeof(pack), 0)) < 0)
        {
            perror("recv");
            ERR_MSG();
            return NULL;
        }
        printf("接收成功\n");
        if(rett == 0)
        {
            do_quit(db, pack.name);
            close(newfd);
            printf("客户端已退出\n");
            return NULL;
        }

        printf("type = %c name = %s passwd = %s\n", pack.type, pack.name, pack.passwd);
        printf("[%s  %d  %d]\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);
        switch(pack.type)
        {
        case 'R':
            do_register(db, newfd, &pack);
            break;
        case 'L':
            do_login(db, newfd, &pack);
            break;
        case 'Q':
            do_quit(db, pack.name);
            break;
        case 'S':
            do_search(db, newfd, &pack);
            break;
        case 'H':
            do_history(db, newfd, pack.name);
            break;
        default:
            break;
        }
    }
    pthread_exit(NULL);

服务器网络相关代码

#include "../inc/op.h"
#include "../inc/dict_socket.h"
#include "../inc/sqlite.h"

int init_socket(const char* ip, short port, struct sockaddr_in* sin)
{
    //创建流式套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0); 
    if(sfd < 0)
    {   
        perror("socket");
        ERR_MSG();
        return -1; 
    }   

    //允许端口快速重用
    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {   
        perror("setsockopt");
        ERR_MSG();
        return -1; 
    }   


    //填充地址信息结构体 绑定
    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(struct sockaddr_in)) < 0)
    {   
        perror("bind");
        ERR_MSG();
        return -1; 
    }   

    
    //监听
    if(listen(sfd, 10) < 0)
    {   
        perror("listen");
        ERR_MSG();
        return -1; 
    }   
    printf("网络初始化成功\n");
    printf("正在监听中\n");

    return sfd;

} 

服务器数据库相关代码

#include "../inc/op.h"
#include "../inc/dict_socket.h"
#include "../inc/sqlite.h"

sqlite3* init_dict_sqlite(sqlite3* db)
{
    char sql[128] = "";
    char buf[64];
    char english[32] = "";
    char chinese[32] = "";

    //打开词典文件
    FILE* pf = fopen("./dict.txt", "r");
    if(NULL == pf)
    {
        perror("fopen");
        return NULL;
    }
    printf("字典文件打开成功\n");

    //打开数据库
    if(sqlite3_open("dict.db", &db) != SQLITE_OK)
    {
        printf("open sqlite3 %s\n", sqlite3_errmsg(db));
        printf("%d\n", sqlite3_errcode(db));
        ERR_MSG();
        return NULL;
    }
    printf("数据库打开成功\n");

    //创建字典表格
    char *errmsg = NULL;
    strcpy(sql, "create table  dict (english1 char , chinese1 char)");
    int ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        //如果表已经存在
        if(ret == 1)
        {
            printf("表格已经存在\n");
            //创建用户表格
            create_user_form(db);
            create_history_form(db);

            return db;
        }
        ERR_MSG();
        return NULL;
    }
    printf("创建字典表格成功\n");


    while(fgets(buf, sizeof(buf), pf) > 0)
    {
        buf[strlen(buf) - 1] = 0;
        sscanf(buf, "%s %[^\n]", english, chinese);
        insert_sqlite(db, english, chinese);
        bzero(english, sizeof(english));
        bzero(chinese, sizeof(chinese));
    }
    printf("字典初始化成功\n");
    create_user_form(db);
    create_history_form(db);
    return db;
}

int insert_sqlite(sqlite3* db, char* english, char* chinese)
{
    char sql[128] = "";
    char *errmsg = NULL;

    sprintf(sql,"insert into dict values  (\"%s\", \"%s\");", english, chinese);
    //printf("sql : %s\n", sql);

    //sqlite3_exec
    if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        printf("sqlite3_exec: %s\n", errmsg);
        printf("%s            %s\n", chinese, english);
        ERR_MSG();
        return -1;
    }
    //printf("插入成功\n");
    return 0;

}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
int create_user_form(sqlite3* db)
{
    char sql[128] = "";
    char *errmsg = NULL;
    //创建用户表格
    strcpy(sql, "create table  if not exists user (name char primary key, passwd char, flag char)");
    int ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("创建用户表格失败:%s\n", errmsg);
        ERR_MSG();
        return -1;
    }
    printf("创建用户表格成功\n");

    bzero(sql, sizeof(sql));
    strcpy(sql,"insert into user values  (\"zhangsan\", \"1234\", \"Y\");");

    //printf("%s\n", sql);
#ifdef TEST
    ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("插入失败:%s\n", errmsg);
        ERR_MSG();
        return -1;
    }
    printf("用户插入成功\n");
#endif
    return 0;
}

int create_history_form(sqlite3* db)
{
    char sql[128] = "";
    char *errmsg = NULL;
    //创建用户表格
    strcpy(sql, "create table  if not exists history (name char , world char, chinese char, time char)");
    int ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("创建历史记录表格失败:%s\n",errmsg);
        ERR_MSG();
        return -1;
    }
    printf("创建历史记录表格成功\n");

    bzero(sql, sizeof(sql));
    strcpy(sql,"insert into history values  (\"zhangsan\", \"1234\", \"15235465\");");

#ifdef TEST
    //printf("%s\n", sql);
    ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("历史记录插入失败:%s\n", errmsg);
        ERR_MSG();
        return -1;
    }
    printf("历史记录插入成功\n");
#endif
    return 0;
}

服务器操作相关代码

#include "../inc/op.h"
#include "../inc/dict_socket.h"
#include "../inc/sqlite.h"

//查找数据库 user 表中是否有该name

static int do_search_name(sqlite3* db, char* name,int* row, int* col, char*** presult) 
{
    char sql[128] = "select * from user where name=";
    sprintf(sql,"%s\"%s\"", sql,name);
    printf("%s\n", sql);
    char *errmsg = NULL;

    if(sqlite3_get_table(db, sql, presult, row, col, &errmsg) != SQLITE_OK)
    {   
        printf("sqlite3_get_table: %s\n", errmsg);
        return -1; 
    }   
    return -1;
}

/*
 *用户注册
 *判断表中是否有该用户
 *当用户存在时,提示注册失败
 *用户不存在, 加入数据库,user表中, 标志位默认置位‘N’ 未登录状态
 */

int do_register(sqlite3* db, int newfd, package* pack)
{
    char sql[128] = "";
    char* errmsg = NULL;
    char** a = NULL;
    int row = 0;
    int col = 0;
    char buf[8] = "";
    //printf("__%d__name__%s__\n", __LINE__,pack->name);
    //printf("__%d__passwd__%s__\n", __LINE__,pack->passwd);

    //先查看user表中是否有该用户
    do_search_name(db, pack->name, &row, &col, &a);
    printf("row = %d col = %d\n", row, col);
    if(0 != row)
    {
        printf("用户已存在\n");
        strcpy(buf, "exist");
        if(send(newfd, buf, sizeof(buf), 0) < 0)
        {
            perror("send");
            return -1;
        }
        return -1;
    }
    bzero(sql, sizeof(sql));

    sprintf(sql, "insert into user values ('%s', '%s', '%c')", pack->name, pack->passwd, 'N');
    //ERR_MSG();
    //printf("%s\n", sql);
    if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {   
        printf("sqlite3_exec: %s\n", errmsg);
        ERR_MSG();
        return -1; 
    }   

    bzero(buf, sizeof(buf));
    strcpy(buf, "success");
    if(send(newfd, buf, sizeof(buf), 0) < 0)
    {
        perror("send");
        return -1;
    }
    return -1;


    return 0;
}

int do_login(sqlite3* db, int newfd, package* pack)
{                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
    char sql[128] = "";
    char* errmsg = NULL;
    char buf[8] = "";
    int row = 0;
    int col = 0;
    char **presult;
    //查看user中是否有该用户
    do_search_name(db, pack->name, &row, &col, &presult);
    if(1 != row)
    {
        strcpy(buf, "notname");
        if(send(newfd, buf, sizeof(buf), 0) < 0)
        {
            perror("send");
            ERR_MSG();
            return -1;
        }
        printf("用户不存在\n");
        return -1;
    }
    ERR_MSG();
    if(presult != NULL)
    {
        int i = 0;
        for(i=0; i<(row+1)*col; i++)
        {
            printf("%d  %-10s", i, presult[i]);
        }
    }
    printf("\n");
    if(strcmp(presult[4], pack->passwd)==0)
    {
        printf("密码一致\n");
        if(strncmp(presult[5], "N",1)==0)
        {
            printf("无重复登录\n");
            strcpy(buf, "success");
            if(send(newfd, buf, sizeof(buf), 0) < 0)
            {
                perror("send");
                ERR_MSG();
                return -1;
            }

            bzero(sql, sizeof(sql));

            sprintf(sql, "update user set flag='Y' where name='%s';", pack->name);
            if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
            {
                ERR_MSG();
                printf("sqlite3_exec %s\n", errmsg);
                return 0;
            }
            return 0;

        }

        strcpy(buf, "chongfu");
        if(send(newfd, buf, sizeof(buf), 0) < 0)
        {
            perror("send");
            ERR_MSG();
            return -1;
        }
        printf("重复登录\n");
        return -1;
    }
    strcpy(buf, "notpw");
        if(send(newfd, buf, sizeof(buf), 0) < 0)
        {
            perror("send");
            ERR_MSG();
            return -1;
        }

    printf("密码不一致\n");
    return 0;

}


static int do_search_world(sqlite3* db, char* english, int* row, int* col, char*** presult) 
{
    char sql[128] = "select * from dict where english1=";
    sprintf(sql,"%s\"%s\"", sql, english);
    printf("%s\n", sql);
    char *errmsg = NULL;

    if(sqlite3_get_table(db, sql, presult, row, col, &errmsg) != SQLITE_OK)
    {   
        printf("sqlite3_get_table: %s\n", errmsg);
        return -1; 
    }   
    return -1;
}

static int save_history(sqlite3* db, char* name, char* english, char* chinese, char*timebuf)
{
    char* errmsg = "";
    char sql[128] = "insert into history values ";
    sprintf(sql,"%s('%s','%s','%s','%s');", sql, name, english, chinese, timebuf);                        
    printf("___%s____\n", sql);
    int ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
    if(ret != SQLITE_OK)
    {
        printf("创建用户表格失败:%s\n", errmsg);
        ERR_MSG();
        return -1;
    }

    return 0;
}


int do_search(sqlite3* db, int newfd, package* pack)
{
    char sql[128] = "";
    char* errmsg = NULL;
    char buf[8] = "";
    int row = 0;
    int col = 0;
    char **presult;
    char chinese[128] = "";
    char english[128] = "";
    time_t result;
    char timebuf[128] = "";
    ERR_MSG();
    printf("___%s___\n", pack->name);

    if(recv(newfd, english, sizeof(english), 0) < 0)
    {
        perror("newfd");
        ERR_MSG();
        return -1;
    }
    english[strlen(english)-1] = 0;

    printf("_____________%s____\n", english);
    do_search_world(db, english, &row, &col, &presult);

    int i = 0;
    for(i=2; i<(row+1)*col; i++)
    {
        printf("__%s__%d__%-10s",__FILE__,__LINE__, presult[i]);
    }
    printf("%d\n", row);
    if(send(newfd, &row, sizeof(row), 0) < 0)
    {
        perror("send");
        ERR_MSG();
        return -1;
    }
    for(i=0; i<row; i++)
    {
        //sleep(2);
        if(send(newfd, presult[2*i+3], 128, 0) < 0)
        {
            perror("send");
            ERR_MSG();
            return -1;
        }
        ERR_MSG();
        printf("-send------%s--------\n", presult[2*i+3]);
        result = time(NULL);
        strcpy(timebuf,asctime(localtime(&result)));
        ERR_MSG();
        printf("-------%s____---\n", timebuf);
        //保存历史记录
        save_history(db, pack->name, english, presult[2*i+3], timebuf);
    }
}

static int do_search_history(sqlite3* db, char* name, int* row, int* col, char*** presult) 
{
    char sql[128] = "select * from history where name=";
    sprintf(sql,"%s\"%s\"", sql, name);
    printf("%s\n", sql);
    char *errmsg = NULL;

    if(sqlite3_get_table(db, sql, presult, row, col, &errmsg) != SQLITE_OK)
    {   
        printf("sqlite3_get_table: %s\n", errmsg);
        return -1; 
    }   
    return -1; 
}

int do_history(sqlite3* db, int newfd, char* name)
{
    char sql[128] = ""; 
    char* errmsg = NULL;
    char buf[8] = ""; 
    int row = 0;
    int col = 0;
    int i = 0;
    char **presult;
    do_search_history(db, name, &row, &col, &presult);
    if(send(newfd, &row, sizeof(row), 0) < 0)
    {   
        perror("send");
        ERR_MSG();
        return -1; 
    }   

    if(0 == row)
    {   
        strcpy(buf, "no");
        if(send(newfd, buf, sizeof(buf), 0) < 0)
        {
            perror("send");
            ERR_MSG();
            return -1; 
        }
        printf("无记录\n");
        return -1; 
    }   
    char sndbuf[256] = ""; 
    for(i=1; i<row+1; i++)
    {   
        sprintf(sndbuf, "%s %s %s %s", presult[i*col+0], presult[i*col+1], presult[col*i+2], presult[col*i+3]);
        sndbuf[strlen(sndbuf)-1] = 0;
        if(send(newfd, sndbuf, sizeof(sndbuf), 0) < 0)
        {
            perror("send");
            ERR_MSG();
            return -1; 
        }
        printf("send %s_________\n", sndbuf);
    }   
    printf("11111111111111111111111111\n");


}

int do_quit(sqlite3* db, char* name)
{
    printf("111111111111111111111111\n");
    char* errmsg = NULL;
    char sql[128] = "update user set flag=\"N\" where name=";
    sprintf(sql, "%s\'%s\'", sql, name);
    printf("%s\n", sql);

    if(sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
    {   
        ERR_MSG();
        printf("sqlite3_exec %s\n", errmsg);
        return 0;
    }   
    printf("name is quit\n");

    return -1; 
}

运行结果

alt