• 电子词典项目


    服务器(server):
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #define N 16
    #define R 1 // user register 用户注册
    #define L 2 // user login 用户登录
    #define Q 3 // query word 查询词
    #define H 4 // history record 历史记录

    #define DATABASE “my.db”
    typedef struct
    {
    int type; //选择操作
    char name[N]; //名字
    char data[256]; // password or word
    } MSG;

    //----------------------建立函数-----------------------------------------------
    //注册表
    void do_register(int acceptfd, MSG *msg, sqlite3 *db);
    //登录
    void do_login(int acceptfd, MSG *msg, sqlite3 *db);
    //查询
    void do_query(int acceptfd, MSG *msg, sqlite3 *db);
    //历史
    void do_history(int acceptfd, MSG *msg, sqlite3 *db);
    //客户端
    void do_client(int acceptfd, sqlite3 *db);
    //搜索字
    int do_searchword(int acceptfd, MSG *msg);
    void getdata(char *date);
    int history_callback(void *arg, int f_num, char **f_value, char **f_name);

    //------------------------------------------------------------------------

    int main(int argc, const char *argv[])
    {
    //句柄指建立一个数据库指针用来保存数据库的所在,通过句柄可以读取调用数据库
    sqlite3 *db;
    //创建进程
    pid_t pid = 0;
    //建立连接接收值
    int acceptfd = 0;

    //健壮性判断
    if (3 != argc)
    {
        printf("usage: %s  ", argv[0]);
        exit(-1);
    }
    //打开数据库
    if (sqlite3_open(DATABASE, &db) != SQLITE_OK)
    {
        // sqlite3_errmsg(db)为获取错误信息函数
        printf("sqlite3 error: %s\n", sqlite3_errmsg(db));
        exit(-1);
    }
    //套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == sockfd)
    {
        perror("socket error");
        exit(-1);
    }
    //填充网络信息结构体
    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    
    socklen_t serveraddr_len = sizeof(serveraddr);
    //套接字绑定
    if (-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len))
    {
        perror("bind error");
        exit(-1);
    }
    //监听
    if (-1 == listen(sockfd, 5))
    {
        perror("listen error");
        exit(-1);
    }
    
    while (1)
    {
        //接受客户端发来的信号
        if (-1 == (acceptfd = accept(sockfd, NULL, NULL)))
        {
            perror("accept error");
            exit(-1);
        }
        //创建父子进程
        pid = fork();
        if (-1 == pid)
        { //进程错误
            perror("fork error");
            exit(-1);
        }
        else if (0 == pid)
        { //子进程
            //客户端数据接受处理
            do_client(acceptfd, db);
        }
        else if (0 < pid)
        { //父进程
            close(acceptfd);
        }
    }
    
    return 0;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    }

    //客户端
    void do_client(int acceptfd, sqlite3 *db)
    {
    //建立结构体类型
    MSG msg;
    //读取客户端发来的信息选择请求
    while (0 < recv(acceptfd, &msg, sizeof(MSG), 0))
    {
    // printf(“type = %d\n”, msg.type);
    // printf(“type = %s\n”, msg.data);
    switch (msg.type)
    {
    case R:
    do_register(acceptfd, &msg, db);
    break;
    case L:
    do_login(acceptfd, &msg, db);
    break;
    case Q:
    do_query(acceptfd, &msg, db);
    break;
    case H:
    do_history(acceptfd, &msg, db);
    break;
    }
    }
    printf(“client quit\n”);
    exit(0);
    return;
    }
    //登录
    //所谓登录就是检验创建是否成功在usr用户下有没有对应的用户信息密码
    void do_login(int acceptfd, MSG *msg, sqlite3 *db)
    {

    char sqlstr[500] = {0};
    char **result = NULL;
    int nrow = 0;
    int ncolumn = 0;
    int ret = 0;
    sprintf(sqlstr, "SELECT * FROM usr WHERE name = '%s' and pass = %s", msg->name, msg->data);
    printf("yfs : [%s]\n", sqlstr);
    if (SQLITE_OK != (ret = sqlite3_get_table(db, sqlstr, &result, &nrow, &ncolumn, NULL)))
    {
        printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
               __FILE__, __LINE__, ret, sqlite3_errmsg(db));
        exit(-1);
    }
    //查询结果便利打印
    int i = 0;
    int j = 0;
    int index;
    
    //查找对应的
    for (i = 0; i < ncolumn; i++)
    {
        printf("%-10s", result[i]);
    }
    printf("\n");
    index = i;
    for (i = 0; i < nrow; i++)
    {
        for (j = 0; j < ncolumn; j++)
        {
            printf("%-10s", result[index++]);
            strncpy(msg->data, "OK", 256);
        }
        printf("\n");
    }
    send(acceptfd, msg, sizeof(MSG), 0);
    //释放内存
    sqlite3_free_table(result);
    return ;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    }
    //注册表
    void do_register(int acceptfd, MSG *msg, sqlite3 *db)
    {
    int ret = 0;
    //组装sql语句
    char sqlstr[500] = {0};
    char return_info[500];
    sprintf(sqlstr, “INSERT INTO usr values(‘%s’,‘%s’)”, msg->name, msg->data);
    //执行sql语句
    printf(“yfs : [%s]\n”, sqlstr);
    if (SQLITE_OK != (ret = sqlite3_exec(db, sqlstr, NULL, NULL, NULL)))
    {
    printf(“文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n”, FILE, LINE, ret, sqlite3_errmsg(db));
    exit(-1);
    }
    else
    {
    sprintf(return_info, “INSERT INTO usr value(‘%s’,‘%s’) is OK”, msg->name, msg->data);
    strcpy(msg->data, return_info);
    }
    send(acceptfd, msg, sizeof(MSG), 0);
    printf(“用户注册成功…\n”);
    }

    //查询
    void do_query(int acceptfd, MSG *msg, sqlite3 *db)
    {
    char sqlstr[500];
    char word[500];
    int found = 0;
    char date[500];
    int ret = 0;
    char *errmsg;
    //保存到word中
    strcpy(word, msg->data);
    //在文件中查询单词
    found = do_searchword(acceptfd, msg);
    // found 找到单词接到函数返回值为 1 未找到返回值 0
    //如果执行成功,还需要保存历史记录
    if (found == 1)
    {
    //获取时间
    getdata(date);
    //通过sqlite3_exec函数插入数据
    sprintf(sqlstr, “INSERT INTO record values(‘%s’,‘%s’,‘%s’)”, msg->name, date, word);
    //执行sql语句
    // printf(“yfs : [%s]\n”, sqlstr);
    if (SQLITE_OK != (ret = sqlite3_exec(db, sqlstr, NULL, NULL, &errmsg)))
    {
    printf(“文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n”, FILE, LINE, ret, sqlite3_errmsg(db));
    exit(-1);
    }
    }
    send(acceptfd, msg, sizeof(MSG), 0);
    return;
    }

    //搜索字
    int do_searchword(int acceptfd, MSG *msg)
    {
    char temp[300];
    int len, result;
    char *p;
    len = strlen(msg->data);
    //打开dict.txt文件
    FILE *fp;
    if (NULL == (fp = fopen(“dict.txt”, “r”)))
    {
    strcpy(msg->data, “dict.txt can not open”);
    send(acceptfd, msg, sizeof(MSG), 0);
    }
    //读取并且比较
    while (fgets(temp, 300, fp) != NULL)
    {
    //设置时间
    result = strncmp(msg->data, temp, len);
    //比较单词
    if (result == 0 && temp[len] == ’ ')
    {
    //读取的单词的地址首位+单词长度 = p
    p = temp + len;
    while (*p == ’ ')
    {
    p++;
    }
    strcpy(msg->data, p);
    fclose(fp);
    //找到就直接退出
    return 1;
    }
    }
    //未找到
    strcpy(msg->data, “not found”);
    fclose(fp);
    return 0;
    }
    //设置时间
    void getdata(char *date)
    {
    time_t t;
    struct tm *tp;
    time(&t);
    tp = localtime(&t);
    sprintf(date, “%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_history(int acceptfd, MSG *msg, sqlite3 *db)
    {
    int ret = 0;
    //组装sql语句
    char sqlstr[500] = {0};
    char *errmsg;
    sprintf(sqlstr, “SELECT * FROM record WHERE name = ‘%s’”, msg->name);
    //执行sql语句
    // printf(“yfs : [%s]\n”, sqlstr);
    if (SQLITE_OK != (ret = sqlite3_exec(db, sqlstr, history_callback, (void *)&acceptfd, &errmsg)))
    {
    printf(“文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n”, FILE, LINE, ret, sqlite3_errmsg(db));
    exit(-1);
    }
    }
    //通过回调函数发送时间和单词
    int history_callback(void *arg, int f_num, char **f_value, char **f_name)
    {
    int acceptfd;
    MSG msg;
    acceptfd = *(int *)arg;
    sprintf(msg.data, “%s : %s”, f_value[1], f_value[2]);
    send(acceptfd, &msg, sizeof(MSG), 0);
    return 0;
    }

    客户机(client):
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #define N 16
    #define R 1 // user register
    #define L 2 // user login
    #define Q 3 // query word
    #define H 4 // history record

    #define DATABASE “my.db”

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

    //-----------------------构建函数---------------------------------------
    //注册
    void do_register(int socketfd, MSG *msg);
    //登录
    int do_login(int socketfd, MSG *msg);
    //查询
    void do_query(int socketfd, MSG *msg);
    //历史
    void do_history(int socketfd, MSG *msg);

    //----------------------------------------------------------------

    int main(int argc,const char * argv[]){
    //定义结构体类型
    MSG msg;

    //健壮性判断
    if(3 != argc){
        printf("usage: %s  ",argv[0]);
        exit(-1);
    }
    //套接字
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(-1 == sockfd){
        perror("socket error");
        exit(-1);
    }
    //填充网络信息结构体
    struct sockaddr_in serveraddr;
    memset(&serveraddr,0,sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    
    socklen_t serveraddr_len = sizeof(serveraddr);
    
    //与服务器建立连接
    if(-1 == connect(sockfd,(struct sockaddr*)&serveraddr,serveraddr_len)){
        perror("connect error");
        exit(-1);
    }
    
    //功能选择向服务器输出值
    int choose = 0;
    while(1){
      	printf("************************************\n");
    	printf("* 1: register   2: login   3: quit *\n");
    	printf("************************************\n");
    	printf("please choose : ");  
    
        if(!scanf("%d",&choose)){
            perror("scanf1 error");
            exit(-1);
        }
    
        switch(choose){
            case 1:
                do_register(sockfd,&msg);
                break;
            case 2:
                if(1 == do_login(sockfd,&msg)){
                    goto NEXT;
                }
                break;
            case 3:
                close(sockfd);
                exit(0);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    NEXT:
    //功能选择

    while(1){
        printf("************************************\n");
    	printf("* 1: query   2: history   3: quit  *\n");
    	printf("************************************\n");
    	printf("please choose : ");
    
        if(!scanf("%d",&choose)){
            perror("scanf2 error");
            exit(-1);
        }
    
        switch(choose){
            case 1:
                do_query(sockfd,&msg);
                break;
            case 2:
                do_history(sockfd,&msg);
                break;
            case 3:
                close(sockfd);
                exit(0);//成功退出
                break;
    
        }
    }
    return 0;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    }

    //注册
    void do_register(int sockfd, MSG *msg){
    //指定操作码
    msg->type = R;
    //输入用户名
    printf(“input your name:>”);
    scanf(“%s”,msg->name);
    //输入密码
    printf(“input your password:>”);
    scanf(“%s”,msg->data);
    //发送数据
    send(sockfd,msg,sizeof(MSG),0);
    //接收数据并输出
    recv(sockfd,msg,sizeof(MSG),0);
    //程序执行结果输出确认
    printf(“register: name=[%s]—password=[%s]\n”,msg->name,msg->data);

    return;
    
    • 1

    }
    //登录
    int do_login(int socketfd, MSG *msg) {
    //设置操作码
    msg->type = L;
    //输入用户名
    printf(“input your name:>”);
    scanf(“%s”,msg->name);
    //输入密码
    printf(“input your password:>”);
    scanf(“%s”,msg->data);
    //发送数据给服务器
    send(socketfd, msg, sizeof(MSG), 0);
    //接收服务器发送的数据
    recv(socketfd, msg, sizeof(MSG), 0);
    //判断是否登录成功
    if(strncmp(msg->data, “OK”, 3) == 0){ //用3 可以防止 OK 和 OKkshdfkj
    //登录成功返回1
    printf(“login : OK\n”);
    return 1;
    }
    //登录失败返回0
    printf(“login error : %s\n”, msg->name);
    return 0;
    }

    //查询
    void do_query(int socketfd, MSG *msg){
    //设置操作码
    msg->type = Q;
    while(1){
    puts(“-----------------------------------------”);
    puts(“---------查询输入要查询的内容-------------”);
    puts(“----------输入#退出返回上一级-------------”);
    printf(“input word :>”);
    scanf(“%s”,msg->data);

        if( 0 == strcmp(msg->data,"#") ){
            break;
        }
        send(socketfd,msg,sizeof(MSG),0);
        recv(socketfd,msg,sizeof(MSG),0);
        printf("正在查询>>> %s\n",msg->data);
    }
    return;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    }
    //历史
    void do_history(int socketfd, MSG *msg){
    msg->type = H;
    send(socketfd,msg,sizeof(MSG),0);
    //确认返回结果
    while(1){
    recv(socketfd,msg,sizeof(MSG),0);
    if(strcmp(msg->data,“OVER”) == 0){
    break;
    }
    printf(“%s\n”,msg->data);
    }
    return;
    }

  • 相关阅读:
    根据多个乱序经纬度计算多边形顶点顺序并绘制到指定地图上
    【LeetCode】622.设计循环队列
    Flink-CDC-快速入手(MySQL为例)
    二、thymeleaf与javaweb的集成
    ELK下载(Elasticsearch、Logstash、Kibana)
    Java如何并行多个if语句呢?
    Hudi Java Client总结|读取Hive写Hudi代码示例
    SpringBoot入门知识
    越南黑客使用新的Delphi动力恶意软件瞄准印度营销人员
    Python数据类型:列表的魔法世界
  • 原文地址:https://blog.csdn.net/weixin_43466725/article/details/126437702