云词典代码分享

终端:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sqlite3.h>
#include <signal.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define DATABASE "my.db"
#define N 16

enum CMD
{
    R = 1,
    L,
    Q,
    H
};

typedef struct sockaddr SA;

typedef struct
{
    int type;
    char name[N];
    char data[256]; // password or word
} MSG;

static sqlite3 *db;

/**
 * @brief 服务器处理注册
 * 得到用户输入用户名和密码并拼接sql语句
 * 执行sql语句
 * 封装执行结果并回发客户端
 */
void do_register(int connfd, MSG *pbuf)
{

    char *errmsg = NULL;
    char sql[300] = "";
    int row = 0;
    int column = 0;
    char **result = NULL;
    //用户名是否存在
    sprintf(sql, "select * from usr where name =\"%s\";", pbuf->name);
    int sr;
    sr = sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);
    printf("%s\n", sql);
    //判断用户信息已经存在
    if (row > 0)
    {
        char ra[300] = {0};
        sprintf(ra, "user\"%s\"already exist!!!", pbuf->name);
        printf("%s\n", ra);
        send(connfd, ra, 300, 0);
    }
    //用户信息不存在,插入用户信息
    else
    {
        //插入数据
        char sqll[300] = "";
        sprintf(sqll, "insert into usr values(\"%s\",\"%s\");", pbuf->name, pbuf->data);

        if (sqlite3_exec(db, sqll, NULL, NULL, &errmsg) != SQLITE_OK)

        {
            fprintf(stderr, "insert err:%s\n", errmsg);
            return;
        }
        else
        {
            printf("insert ok\n");
            char i[300] = "register :ok";
            send(connfd, i, 300, 0);
        }
    }
}

/**
 * @brief 服务器处理登录
 * 得到用户输入用户名和密码并拼接sql语句
 * 执行sql语句
 * 封装执行结果并回发客户端
 */
void do_login(int connfd, MSG *pbuf)
{
    int sr;
    char **result = NULL;
    int row = 0;    //行
    int column = 0; //列
    int k = 0;      //result下标
    char *errmsg = NULL;
    char sql[300] = "";

    //用户名
    sprintf(sql, "select * from usr where name=\"%s\";", pbuf->name);
    sr = sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);
    //用户信息存在
    if (row > 0)
    {
        row = 0;
        char s[300] = "";
        //用户名加密码
        sprintf(s, "select * from usr where name=\"%s\" and pass= \"%s\";", pbuf->name, pbuf->data);
        int srr;
        srr = sqlite3_get_table(db, s, &result, &row, &column, &errmsg);
        if (row > 0)
        //密码正确
        {
            char c[300] = "login success";
            send(connfd, c, 300, 0);
        }
        else
        //密码错误
        {
            printf("%s\n", s);
            char b[300] = "name err";
            send(connfd, b, 300, 0);
        }
    }
    else
    {
        //不存在,先注册
        char a[300] = "please register";
        send(connfd, a, 300, 0);
    }
}

/*
 * @brief 查询单词释义
 * @return 查询成功返回1 失败返回0
 */
int do_searchword(int connfd, MSG *pbuf)
{
    char **result = NULL;
    int row = 0;    //行
    int column = 0; //列
    char *errmsg = NULL;
    char sql[300] = "";
    //打开表dic
    // if (sqlite3_exec(db, "create table dic(word char,parse char);", NULL, NULL, &errmsg) != SQLITE_OK)

    // {
    //     fprintf(stderr, "create err:%s\n", errmsg);
    // }
    // else
    //     printf("dic open ok\n");
    // //设置键值
    if (sqlite3_exec(db, "create table dic( word char primary key,parse char);", NULL, NULL, &errmsg) != SQLITE_OK)

    {
        fprintf(stderr, "create key err:%s\n", errmsg);
    }
    sprintf(sql, "select * from dic where word = \"%s\";", pbuf->data);
    if (sqlite3_get_table(db, sql, &result, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "select err:%s\n", errmsg);
    }
    if (row == 0)
    { //没找到
        strcpy(pbuf->data,"该单词不存在");
        printf("%s\n", pbuf->data);
        send(connfd, pbuf,sizeof(MSG), 0);
        memset(pbuf->data,0,sizeof(pbuf->data));
        return 0;
    }

    else if (row > 0)
    {
        printf("row:%d  cou:%d\n", row, column); //查询的单词信息
        int k = 3;                               //下表
        for (int i = 0; i < row; i++)
        {
            for (int j = 1; j < column; j++)//每行就打印一个字符串
            {
                //k,只能查三个单词
                sprintf(pbuf->data,"%s " ,result[k]); //j=0,result[k]最后越界
                send(connfd, pbuf, sizeof(MSG), 0);
                k=k+2;
                memset(pbuf->data,0,sizeof(pbuf->data));
            }
            strcpy(pbuf->data, "\n");
            send(connfd, pbuf, sizeof(MSG), 0);
        }
        strcpy(pbuf->data, "over");
        send(connfd, pbuf, sizeof(MSG), 0);
        return 1;
    }
}

/**
 * @brief 返回当前的时间,存到date中
 * @return 
 */
void get_date(char *date)
{
    time_t t;
    struct tm *tp;

    time(&t);

    tp = localtime(&t);

    sprintf(date, "%d-%02d-%02d %02d:%02d:%02d", tp->tm_year + 1900,
            tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec);

    strftime(date, 64, "%Y-%m-%d %H:%M:%S", tp);

    return;
}

/**
 * @brief 服务器处理查询
 * 查询单词释义
 * 把本次查询添加到查询历史中
 */
void do_query(int connfd, MSG *pbuf)
{
    char *errmsg = NULL;
    int ret;
    char buf[300] = "";
    strcpy(buf, pbuf->data);
    ret = do_searchword(connfd, pbuf);
    if (ret == 1)
    {
        //打开表
        // if (sqlite3_exec(db, "create table record(name char,data char,word char);", NULL, NULL, &errmsg) != SQLITE_OK)

        // {
        //     fprintf(stderr, "create err:%s\n", errmsg);
        // }
        // else
        //     printf("dic open ok\n");
        // // //设置键值
        // if (sqlite3_exec(db, "create table record(name char primary key,data char,word char);", NULL, NULL, &errmsg) != SQLITE_OK)

        // {
        //     fprintf(stderr, "create key err:%s\n", errmsg);
        // }
        char sqll[300] = "";
        char date[128] = "";
        get_date(date);
        sprintf(sqll, "insert into record values(\"%s\",\"%s\",\"%s\");", pbuf->name, date, buf);

        if (sqlite3_exec(db, sqll, NULL, NULL, &errmsg) != SQLITE_OK)
        {
            fprintf(stderr, "insert err:%s\n", errmsg);
            return;
        }
        else
        {
            printf("insert ok\n");
        }
    }
}

/**
 * @brief 查询历史处理
 * 根据用户名来查找查询历史,并将结果返回给客户端
 * 执行sql语句
 * 封装执行结果并回发客户端
 */
void do_history(int connfd, MSG *pbuf)
{
    char **result = NULL;
    int row = 0;    //行
    int column = 0; //列
    char *errmsg = NULL;
    char sql[300] = "";
    // sprintf(sql, "select *from record where name= \"%s\";", pbuf->name);
    sprintf(sql, "select date,word from record where name= \"%s\";", pbuf->name);//**注意**
    if (sqlite3_get_table(db, sql, &result, &row, &column, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "select err:%s\n", errmsg);
    }
     printf("row:%d  cou:%d\n", row, column); //查询的单词信息
    if (row > 0)
    {              //查询的信息
        int k = 0; //下表
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < column; j++)
            {

                sprintf(pbuf->data, "%s ", result[k++]);
                 printf("%s\n", pbuf->data);
                send(connfd, pbuf, sizeof(MSG), 0);
            }
            strcpy(pbuf->data, "\n");
            send(connfd, pbuf, sizeof(MSG), 0);
        }
        strcpy(pbuf->data, "over");
        send(connfd, pbuf, sizeof(MSG), 0);
    }

    return;
}

/**
 * @brief do_client 处理客户端请求
 * @param connfd 客户端fd
 * @param db 数据库句柄
 */
void do_client(int connfd)
{
    MSG buf;
    while (recv(connfd, &buf, sizeof(buf), 0) > 0)
    {
        switch (buf.type)
        {
        case R:
            printf("will reg\n");
            do_register(connfd, &buf);
            break;
        case L:
            printf("will login\n");
            do_login(connfd, &buf);
            break;
        case Q:
            printf("will query\n");
           
            do_query(connfd, &buf);
            break;
        case H:
            printf("will history\n");
            do_history(connfd, &buf);
            break;
        default:
            break;
        }
    }

    exit(0);
}

int main(int argc, char *argv[])
{

    int listenfd, connfd;
    struct sockaddr_in myaddr;
    pid_t pid;
    MSG buf;

    if (argc < 3)
    {
        printf("Usage : %s <ip> <port>\n", argv[0]);
        exit(-1);
    }

    //打开数据库
    // if (sqlite3_open(DATABASE, &db) < 0)
    // {
    //     printf("fail to sqlite3_open : %s\n", sqlite3_errmsg(db));
    //     return -1;
    // }
    char *errmsg = NULL;
    if (sqlite3_open("./my.db", &db) != SQLITE_OK)
    {
        fprintf(stderr, "open err:%s\n", sqlite3_errmsg(db));
        return -1;
    }
    printf("open ok\n");
    // //打开表
    // if (sqlite3_exec(db, "create table usr( name char, pass char);", NULL, NULL, &errmsg) != SQLITE_OK)

    // {
    //     fprintf(stderr, "create err:%s\n", errmsg);
    // }
    // else
    //     printf("create ok\n");
    //设置键值,键值唯一,不会重复
    if (sqlite3_exec(db, "create table usr(name char primary key,pass char);", NULL, NULL, &errmsg) != SQLITE_OK)

    {
        fprintf(stderr, "create key err:%s\n", errmsg);
    }

    //创建服务器socket
    listenfd = socket(PF_INET, SOCK_STREAM, 0);
    if (listenfd < 0)
    {
        perror("fail to socket");
        exit(-1);
    } //
    bzero(&myaddr, sizeof(myaddr));

    myaddr.sin_family = PF_INET;
    myaddr.sin_port = htons(atoi(argv[2]));
    myaddr.sin_addr.s_addr = inet_addr(argv[1]);
    if (bind(listenfd, (SA *)&myaddr, sizeof(myaddr)) < 0)
    {
        perror("fail to bind");
        exit(-1);
    }

    // XXX int listen(int sockfd, int backlog);
    if (listen(listenfd, 5) < 0)
    {
        perror("fail to listen");
        exit(-1);
    }

    //并发服务器模型
    while (1)
    {
        if ((connfd = accept(listenfd, NULL, NULL)) < 0)
        {
            perror("fail to accept");
            exit(-1);
        }
        pid = fork();
        if (pid == -1)
        {
            perror("fail to fork\n");
            exit(-1);
        }
        else if (pid == 0)
        { //子进程
            printf("a user comming\n");
            do_client(connfd);
        }
        else
        { //父进程
            close(connfd);
        }
    }
}

客户端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sqlite3.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define N 16
typedef struct sockaddr SA;

enum CMD
{
    R = 1, //注册
    L,     //登录
    Q,     //查询
    H      //历史
};

typedef struct
{
    int type;
    char name[N];
    char data[256]; // password or word
} MSG;
static sqlite3 *db;
/**
 * @brief 客户端注册
 * 用户输入用户名和密码
 * 封装消息
 * 发送
 * 接收并输出结果
 */
void do_register(int sockfd, MSG *pbuf)
{
    pbuf->type = R;
    //接收数据
    char r[300] = "";

    //插入数据
    printf("input name : ");
    fgets(pbuf->name, sizeof(pbuf->name), stdin);
    if (pbuf->name[strlen(pbuf->name) - 1] == '\n')
        pbuf->name[strlen(pbuf->name) - 1] = '\0';
    printf("input password : ");
    fgets(pbuf->data, sizeof(pbuf->data), stdin);
    if (pbuf->data[strlen(pbuf->data) - 1] == '\n')
        pbuf->data[strlen(pbuf->data) - 1] = '\0';
    send(sockfd, pbuf, sizeof(MSG), 0);
    //用户名已存在或注册成功
    recv(sockfd, r, 300, 0);
    printf("%s\n", r);
}

/**
 * @brief 客户端登录
 * 用户输入用户名和密码
 * 封装消息
 * 发送
 * 接收并输出结果
 * @return 成功返回1 失败返回0
 */
int do_login(int sockfd, MSG *pbuf)
{
    char r[300] = "";
    pbuf->type = L;
    printf("input name: ");
    fgets(pbuf->name, sizeof(pbuf->name), stdin);
    if (pbuf->name[strlen(pbuf->name) - 1] == '\n')
        pbuf->name[strlen(pbuf->name) - 1] = '\0';
    printf("input password: ");
    fgets(pbuf->data, sizeof(pbuf->data), stdin);
    if (pbuf->data[strlen(pbuf->data) - 1] == '\n')
        pbuf->data[strlen(pbuf->data) - 1] = '\0';
    send(sockfd, pbuf, sizeof(MSG), 0);
    //接收执行结果
    recv(sockfd, r, 300, 0);
    printf("%s\n", r);
    if (strcmp(r, "login success") == 0)
        return 1;
    else
        return 0;
}

/**
 * @brief 客户端查询
 * 查询历史
 */
void do_history(int sockfd, MSG *pbuf)
{

    pbuf->type = H;
    send(sockfd, pbuf, sizeof(MSG), 0);
    while (1)
    {
        recv(sockfd, pbuf, sizeof(MSG), 0);
        if (!strcmp(pbuf->data, "over"))
            break;
        printf("%s", pbuf->data);
        memset(pbuf->data, 0, sizeof(pbuf->data));
    }
}

/**
 * @brief 客户端查询
 * 输入单词或“#”
 * 封装消息
 * 发送
 * 接收并输出结果
 */
void do_query(int sockfd, MSG *pbuf)
{
    pbuf->type = Q;
    while (1)
    {
        printf("input word(# to quit): ");
        fgets(pbuf->data, sizeof(pbuf->data), stdin);
        if (pbuf->data[strlen(pbuf->data) - 1] == '\n')
            pbuf->data[strlen(pbuf->data) - 1] = '\0';
        if (strcmp(pbuf->data, "#") == 0)
            return;
        send(sockfd, pbuf, sizeof(MSG), 0);
        //接收查询信息
        while (1)
        {
            recv(sockfd, pbuf, sizeof(MSG), 0);
            if (!strcmp(pbuf->data, "over"))
                break;
            if (!strcmp(pbuf->data, "该单词不存在"))
            {
                printf("%s \n", pbuf->data);
                break;
            }
            printf("%s \n", pbuf->data);
        }
    }
}

void enter_query(int sockfd, MSG *buf)
{
    int input;
    char cleanbuf[64];

    while (1)
    {
        printf("***********************************************\n");
        printf("* 1: query_word   2: history_record   3: quit *\n");
        printf("***********************************************\n");
        printf("please choose : ");
        //获取用户输入
        if (scanf("%d", &input) == 0)
        {
            fgets(cleanbuf, 64, stdin); //类型错误需要重新清除输入缓冲区
            continue;
        }
        getchar();

        switch (input)
        {
        case 1:
            printf("\n");
            do_query(sockfd, buf);
            printf("\n");
            break;
        case 2:
            printf("\n");
            do_history(sockfd, buf);
            printf("\n");
            break;
        case 3:
            return;
        default:
            break;
        }
    }
}

int main(int argc, char *argv[])
{
    int sockfd, login = 0;
    struct sockaddr_in servaddr;
    MSG buf;
    char clean[64];

    if (argc < 3)
    {
        printf("Usage : %s <serv_ip> <serv_port>\n", argv[0]);
        exit(-1);
    }

    //创建客户端socket
    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("fail to socket");
        exit(-1);
    }
    int optval = 1;
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = PF_INET;
    servaddr.sin_port = htons(atoi(argv[2]));
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

    //连接服务器
    if (connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) < 0)
    {
        perror("fail to connect");
        exit(-1);
    }

    int input;
    char cleanbuf[64];
    while (1)
    {
        printf("************************************\n");
        printf("* 1: register   2: login   3: quit *\n");
        printf("************************************\n");
        printf("please choose : ");
        //获取用户输入
        if (scanf("%d", &input) == 0)
        {
            fgets(cleanbuf, 64, stdin); //类型错误需要重新清除输入缓冲区
            continue;
        }
        getchar(); //回收回车

        switch (input)
        {
        case 1:
            do_register(sockfd, &buf);
            break;
        case 2:
            if (do_login(sockfd, &buf) == 1)
            {
                enter_query(sockfd, &buf);
            }
            break;
        case 3:
            close(sockfd);
            exit(0);
            break;
        default:
            break;
        }
    }
}

  • 28
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值