基于TCP的在线词典系统(分阶段实现)

news2024/10/5 14:42:07

1.功能说明

一共四个功能:

                注册

                登录

                查询单词

                查询历史记录

单词和解释保存在文件中,单词和解释只占一行,

一行最多300个字节,单词和解释之间至少有一个空格。

2.功能演示

3、分阶段完成各个功能

3.1 完成服务器和客户端的连接

service.c

#include <head.h>

int main(int argc, const char *argv[])
{
    // 入参合理性检查
    if (3 != argc)
    {
        printf("usage error:%s <port> <ip>\n", argv[0]);
        exit(-1);
    }
    // 创建套接字
    int sockfd;
    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("sockfd error");
        exit(-1);
    }
    // 填充服务器网络信息结构体
    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);
    struct sockaddr_in clientaddr;
    socklen_t clientaddr_len = sizeof(clientaddr);
    memset(&clientaddr, 0, sizeof(clientaddr));
    // 绑定
    if (-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len))
    {
        perror("bind error");
        exit(-1);
    }
    // 监听
    printf("%d\n", sockfd);
    if (listen(sockfd, 5) < 0)
    {
        perror("fail to listen");
        exit(-1);
    }
    int acceptfd;
    while (1)
    {
        acceptfd = 0;
        printf("阻塞等待客户端连接...\n");
        if (-1 == (acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientaddr_len)))
        {
            perror("accept errror");
            exit(-1);
        }
        printf("111111111\n");
        printf("客户端[%s][%d]连接成功...\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
        pid_t pid;
        pid = fork();
        if (pid == -1)
        {
            perror("fork error");
            exit(-1);
        }
        else if (pid == 0)
        {
            // 子进程
        }
        else
        {
            // 父进程
            wait(NULL);
        }
    }

    return 0;
}

client.c

#include <head.h>
void print_menu();
int main(int argc, const char *argv[])
{
    // 入参合理性检查
    if (3 != argc)
    {
        printf("usage error:%s <ip> <port>\n", argv[1]);
        exit(-1);
    }
    // 创建套接字
    int sockfd;
    if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
    {
        perror("socket error");
        exit(-1);
    }
    // 填充服务器网络信息结构体
    struct sockaddr_in serveraddr;
    socklen_t serveraddr_len = sizeof(serveraddr);
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));
    if (-1 == connect(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len))
    {
        perror("connect error");
        exit(-1);
    }
    printf("连接服务器成功...\n");
    while (1)
    {
        print_menu();
        sleep(10);
    }
    return 0;
}
void print_menu()
{
    printf("-------------------------------------\n");
    printf("|    1.regist     2.login     3.quit|\n");
    printf("-------------------------------------\n");
    return;
}

3.2 新增完成注册和退出功能

service.c

#include <head.h>
#include <sqlite3.h> //sqlite3
#define R 1
#define L 2
#define Q 3
#define H 4
#define DATABASE "test.db"
typedef struct _MSG
{
    int type;
    char name[32];
    char data[128];
} msg_t;
void do_regist(msg_t *msg, int acceptfd, sqlite3 *my_db);
void do_quit(msg_t *msg, int acceptfd, sqlite3 *my_db);
int main(int argc, const char *argv[])
{
    // 入参合理性检查
    if (3 != argc)
    {
        printf("usage error:%s <port> <ip>\n", argv[0]);
        exit(-1);
    }
    // 创建数据库
    sqlite3 *my_db;
    if (SQLITE_OK != sqlite3_open(DATABASE, &my_db))
    {
        printf("sqlite3 open error:%s\n", sqlite3_errmsg(my_db));
        exit(-1);
    }
    // 创建套接字
    int sockfd;
    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("sockfd error");
        exit(-1);
    }
    // 填充服务器网络信息结构体
    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);
    struct sockaddr_in clientaddr;
    socklen_t clientaddr_len = sizeof(clientaddr);
    memset(&clientaddr, 0, sizeof(clientaddr));
    // 绑定
    if (-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len))
    {
        perror("bind error");
        exit(-1);
    }
    // 监听
    printf("%d\n", sockfd);
    if (listen(sockfd, 5) < 0)
    {
        perror("fail to listen");
        exit(-1);
    }
    int acceptfd;
    msg_t msg;
    while (1)
    {
        acceptfd = 0;
        printf("阻塞等待客户端连接...\n");
        if (-1 == (acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientaddr_len)))
        {
            perror("accept errror");
            exit(-1);
        }
        printf("111111111\n");
        printf("客户端[%s][%d]连接成功...\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
        pid_t pid;
        pid = fork();
        if (pid == -1)
        {
            perror("fork error");
            exit(-1);
        }
        else if (pid == 0)
        {
            while (1)
            {
                if (-1 == recv(acceptfd, &msg, sizeof(msg), 0))
                {
                    perror("recv error");
                    exit(-1);
                }
                // printf("msg_type = %d\n", msg.type);
                // printf("msg.name = %s\n", msg.name);
                // printf("msg.data = %s\n", msg.data);
                switch (msg.type)
                {
                case R:
                    do_regist(&msg, acceptfd, my_db);
                    break;
                case L:
                    break;
                case Q:
                    printf("客户端[%s][%d]退出了...\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                    do_quit(&msg, acceptfd, my_db);
                    break;
                case H:

                    break;
                }
            }
            // 子进程
        }
        else
        {
            // 父进程
            close(acceptfd);
            wait(NULL);
        }
    }

    return 0;
}
void do_regist(msg_t *msg, int acceptfd, sqlite3 *my_db)
{
    char sqlstr[512] = {0};
    char *errmsg;
    // printf("msg]msg.type = %d\n", msg->type);
    // printf("[msg]msg.name = %s\n", msg->name);
    // printf("[msg]msg.data = %s\n", msg->data);
    sprintf(sqlstr, "insert into user values('%s','%s')", msg->name, msg->data);
    // printf("[do_regist]sqlstr = %s\n", sqlstr);
    if (sqlite3_exec(my_db, sqlstr, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        printf("errmsg = %s\n", errmsg);
        sprintf(msg->data, "user already exit,regist fail");
    }
    else
    {
        strcpy(msg->data, "OK");
    }
    // printf("[do_regist_send]msg.type = %d\n", msg->type);
    // printf("[do_regist_send]msg.name = %s\n", msg->name);
    // printf("[do_regist_send]msg.data = %s\n", msg->data);
    if (-1 == send(acceptfd, msg, sizeof(msg_t), 0))
    {
        perror("send error");
        exit(-1);
    }
    return;
}
void do_quit(msg_t *msg, int acceptfd, sqlite3 *my_db)
{
    exit(-1);
}

client.c

#include <head.h>
#include <sqlite3.h> //sqlite3
#define R 1
#define L 2
#define Q 3
#define H 4
#define DATABASE "test.db"
typedef struct _MSG
{
    int type;
    char name[32];
    char data[128];
} msg_t;
void print_menu();
void login_user(msg_t msg, int sockfd);
void exit_system(msg_t *msg, int sockfd);
int regist_user(msg_t *msg, int sockfd);
int check_user(msg_t msg, int sockfd);
int main(int argc, const char *argv[])
{
    // 入参合理性检查
    if (3 != argc)
    {
        printf("usage error:%s <ip> <port>\n", argv[1]);
        exit(-1);
    }
    // 创建套接字
    sqlite3 *my_db;
    if (SQLITE_OK != sqlite3_open(DATABASE, &my_db))
    {
        printf("sqlite3 open error:%s\n", sqlite3_errmsg(my_db));
        exit(-1);
    }
    int sockfd;
    if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
    {
        perror("socket error");
        exit(-1);
    }

    // 填充服务器网络信息结构体
    struct sockaddr_in serveraddr;
    socklen_t serveraddr_len = sizeof(serveraddr);
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));
    int choose = 0;
    msg_t msg;
    if (-1 == connect(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len))
    {
        perror("connect error");
        exit(-1);
    }
    printf("连接服务器成功...\n");
    while (1)
    {
        print_menu();
        printf("请输入您的选择:");
        scanf("%d", &choose);
        switch (choose)
        {
        case R:
            regist_user(&msg, sockfd);
        case L:
            login_user(msg, sockfd);
            break;
        case Q:
            exit_system(&msg, sockfd);
            break;
        }
    }

    return 0;
}
void print_menu()
{
    printf("-------------------------------------\n");
    printf("|    1.regist     2.login     3.quit|\n");
    printf("-------------------------------------\n");
    return;
}
void exit_system(msg_t *msg, int sockfd)
{
    system("clear");
    msg->type = Q;
    if (-1 == send(sockfd, msg, sizeof(msg_t), 0))
    {
        perror("send error");
        exit(-1);
    }
    close(sockfd);
    printf("欢迎下次使用基于TCP的在线词典系统...\n");
    exit(-1);
}
int check_user(msg_t msg, int sockfd)
{
    printf("[check_user_send]msg.type = %d\n", msg.type);
    printf("[check_user_send]msg.name = %s\n", msg.name);
    printf("[check_user_send]msg.data = %s\n", msg.data);
    if (-1 == send(sockfd, &msg, sizeof(msg), 0))
    {
        perror("send error");
        exit(-1);
    }
    memset(&msg, 0, sizeof(msg));
    if (-1 == recv(sockfd, &msg, sizeof(msg), 0))
    {
        perror("recv error");
        exit(-1);
    }
    printf("[check_user_recv]msg.type = %d\n", msg.type);
    printf("[check_user_recv]msg.name = %s\n", msg.name);
    printf("[check_user_recv]msg.data = %s\n", msg.data);
    if (strcmp(msg.data, "user already exit,regist fail") == 0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}
int regist_user(msg_t *msg, int sockfd)
{
    memset(msg, 0, sizeof(msg_t));
    msg->type = R;
    printf("[注册]请输入用户名:");
    scanf("%s", msg->name);
    printf("[注册]请输入密码:");
    scanf("%s", msg->data);
    // printf("[regist_user]msg.type = %d\n", msg->type);
    // printf("[regist_user]msg.name = %s\n", msg->name);
    // printf("[regist_user]msg.data = %s\n", msg->data);
    if (-1 == send(sockfd, msg, sizeof(msg_t), 0))
    {
        perror("send error");
        exit(-1);
    }
    // printf("[regist_send]msg.type = %d\n", msg->type);
    // printf("[regist_send]msg.name = %s\n", msg->name);
    // printf("[regist_send]msg.data = %s\n", msg->data);
    memset(msg, 0, sizeof(msg));
    if (-1 == recv(sockfd, msg, sizeof(msg_t), 0))
    {
        perror("recv error");
        exit(-1);
    }
    // printf("[regist_recv]msg.type = %d\n", msg->type);
    // printf("[regist_recv]msg.name = %s\n", msg->name);
    // printf("[regist_recv]msg.data = %s\n", msg->data);
    if (strncmp(msg->data, "OK", 3) == 0)
    {
        printf("注册成功...\n");
        return 1;
    }
    printf("用户名已存在,注册失败...\n");
    return 0;
}
void login_user(msg_t msg, int sockfd)
{
    return;
}

结果图:

3.3 新增完成登录功能(密码和用户名都正确才能登录成功)

service.c

#include <head.h>
#include <sqlite3.h> //sqlite3
#define R 1
#define L 2
#define Q 3
#define S 4
#define H 5
#define E 6
#define DATABASE "test.db"
typedef struct _MSG
{
    int type;
    char name[32];
    char data[128];
} msg_t;
void do_regist(msg_t *msg, int acceptfd, sqlite3 *my_db);
void do_quit(msg_t *msg, int acceptfd, sqlite3 *my_db);
void do_login(msg_t *msg, int acceptfd, sqlite3 *my_db);
int main(int argc, const char *argv[])
{
    // 入参合理性检查
    if (3 != argc)
    {
        printf("usage error:%s <port> <ip>\n", argv[0]);
        exit(-1);
    }
    // 创建数据库
    sqlite3 *my_db;
    if (SQLITE_OK != sqlite3_open(DATABASE, &my_db))
    {
        printf("sqlite3 open error:%s\n", sqlite3_errmsg(my_db));
        exit(-1);
    }
    // 创建套接字
    int sockfd;
    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("sockfd error");
        exit(-1);
    }
    // 填充服务器网络信息结构体
    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);
    struct sockaddr_in clientaddr;
    socklen_t clientaddr_len = sizeof(clientaddr);
    memset(&clientaddr, 0, sizeof(clientaddr));
    // 绑定
    if (-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len))
    {
        perror("bind error");
        exit(-1);
    }
    // 监听
    printf("%d\n", sockfd);
    if (listen(sockfd, 5) < 0)
    {
        perror("fail to listen");
        exit(-1);
    }
    int acceptfd;
    msg_t msg;
    while (1)
    {
        acceptfd = 0;
        printf("阻塞等待客户端连接...\n");
        if (-1 == (acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &clientaddr_len)))
        {
            perror("accept errror");
            exit(-1);
        }
        printf("111111111\n");
        printf("客户端[%s][%d]连接成功...\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
        pid_t pid;
        pid = fork();
        if (pid == -1)
        {
            perror("fork error");
            exit(-1);
        }
        else if (pid == 0)
        {
            while (1)
            {
                if (-1 == recv(acceptfd, &msg, sizeof(msg), 0))
                {
                    perror("recv error");
                    exit(-1);
                }
                // printf("msg_type = %d\n", msg.type);
                // printf("msg.name = %s\n", msg.name);
                // printf("msg.data = %s\n", msg.data);
                switch (msg.type)
                {
                case R:
                    do_regist(&msg, acceptfd, my_db);
                    break;
                case L:
                    do_login(&msg, acceptfd, my_db);
                    break;
                case Q:
                    printf("客户端[%s][%d]退出了...\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
                    do_quit(&msg, acceptfd, my_db);
                    break;
                case H:

                    break;
                }
            }
            // 子进程
        }
        else
        {
            // 父进程
            close(acceptfd);
            wait(NULL);
        }
    }

    return 0;
}
void do_regist(msg_t *msg, int acceptfd, sqlite3 *my_db)
{
    char sqlstr[512] = {0};
    char *errmsg;
    // printf("msg]msg.type = %d\n", msg->type);
    // printf("[msg]msg.name = %s\n", msg->name);
    // printf("[msg]msg.data = %s\n", msg->data);
    sprintf(sqlstr, "insert into user values('%s','%s')", msg->name, msg->data);
    // printf("[do_regist]sqlstr = %s\n", sqlstr);
    if (sqlite3_exec(my_db, sqlstr, NULL, NULL, &errmsg) != SQLITE_OK)
    {
        printf("errmsg = %s\n", errmsg);
        sprintf(msg->data, "user already exit,regist fail");
    }
    else
    {
        strcpy(msg->data, "OK");
    }
    // printf("[do_regist_send]msg.type = %d\n", msg->type);
    // printf("[do_regist_send]msg.name = %s\n", msg->name);
    // printf("[do_regist_send]msg.data = %s\n", msg->data);
    if (-1 == send(acceptfd, msg, sizeof(msg_t), 0))
    {
        perror("send error");
        exit(-1);
    }
    return;
}
int callback(void *arg, int ncolumn, char **f_value, char **f_name)
{
    int i = 0;
    int flag = 0;
    msg_t *msg_callback = (msg_t *)arg;
    if (0 == flag)
    {
        // 先打印字段名
        for (i = 0; i < ncolumn; i++)
        {
            strcpy(msg_callback->data, "user or passwd ereror");
        }
        flag = 1;
    }
    // 再打印字段的值
    for (i = 0; i < ncolumn; i++)
    {
        strcpy(msg_callback->data, "OK");
    }
    return 0; // 这里的回调函数要求必须有返回值 如果没有会报错 query aborted
}

void do_login(msg_t *msg, int acceptfd, sqlite3 *my_db)
{
    char sqlstr[512] = {0};
    char *errmsg;
    printf("[msg]msg.type = %d\n", msg->type);
    printf("[msg]msg.name = %s\n", msg->name);
    printf("[msg]msg.data = %s\n", msg->data);
    sprintf(sqlstr, "select * from user where name='%s' and passwd='%s'", msg->name, msg->data);
    printf("[do_regist]sqlstr = %s\n", sqlstr);
    if (sqlite3_exec(my_db, sqlstr, callback, (void *)msg, &errmsg) != SQLITE_OK)
    {
        printf("errmsg = %s\n", errmsg);
        exit(-1);
        // sprintf(msg->data, "user or passwd ereror");
    }

    // else
    // {
    //     strcpy(msg->data, "OK");
    // }
    printf("[do_regist_send]msg.type = %d\n", msg->type);
    printf("[do_regist_send]msg.name = %s\n", msg->name);
    printf("[do_regist_send]msg.data = %s\n", msg->data);
    if (-1 == send(acceptfd, msg, sizeof(msg_t), 0))
    {
        perror("send error");
        exit(-1);
    }
    return;
}
void do_quit(msg_t *msg, int acceptfd, sqlite3 *my_db)
{
    exit(-1);
}

client.c

#include <head.h>
#include <sqlite3.h> //sqlite3
#define R 1
#define L 2
#define Q 3
#define S 4
#define H 5
#define E 6
#define DATABASE "test.db"
typedef struct _MSG
{
    int type;
    char name[32];
    char data[128];
} msg_t;
void print_menu();
int login_user(msg_t *msg, int sockfd, sqlite3 *my_db);
void exit_system(msg_t *msg, int sockfd);
int regist_user(msg_t *msg, int sockfd);
int check_user(msg_t msg, int sockfd);
int search_world(msg_t *msg, int sockfd, sqlite3 *my_db);
int exit_search(msg_t *msg, int sockfd);
void query_menu();
int main(int argc, const char *argv[])
{
    // 入参合理性检查
    if (3 != argc)
    {
        printf("usage error:%s <ip> <port>\n", argv[1]);
        exit(-1);
    }
    // 创建套接字
    sqlite3 *my_db;
    if (SQLITE_OK != sqlite3_open(DATABASE, &my_db))
    {
        printf("sqlite3 open error:%s\n", sqlite3_errmsg(my_db));
        exit(-1);
    }
    int sockfd;
    if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0)))
    {
        perror("socket error");
        exit(-1);
    }

    // 填充服务器网络信息结构体
    struct sockaddr_in serveraddr;
    socklen_t serveraddr_len = sizeof(serveraddr);
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));
    int choose = 0;
    msg_t msg;
    if (-1 == connect(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len))
    {
        perror("connect error");
        exit(-1);
    }
    printf("连接服务器成功...\n");
NEXT2:
    while (1)
    {

        print_menu();

        printf("请输入您的选择(1-3):");
        scanf("%d", &choose);

        switch (choose)
        {
        case R:
            regist_user(&msg, sockfd);
            break;
        case L:
            if (login_user(&msg, sockfd, my_db) == 1)
            {
                goto NEXT;
            }
            else
            {
                break;
            }

        case Q:
            close(sockfd);
            // system("clear");
            printf("欢迎下次使用基于TCP的在线词典系统...\n");
            exit(0);
        }
    }
NEXT:
    while (1)
    {
        system("clear");
        query_menu();
        printf("请输入您的选择(4-6):");
        scanf("%d", &choose);
        switch (choose)
        {
        case S:
            search_world(&msg, sockfd, my_db);
            break;
        case H:
            break;
        case E:
            goto NEXT2;
            break;
        }
    }

    return 0;
}
void print_menu()
{
    printf("-------------------------------------\n");
    printf("|  1.regist     2.login     3.quit  |\n");
    printf("-------------------------------------\n");
    return;
}
void query_menu()
{
    printf("-------------------------------------\n");
    printf("|  4.search    5.history    6.quit  |\n");
    printf("-------------------------------------\n");
    return;
}
void exit_system(msg_t *msg, int sockfd)
{
    system("clear");
    msg->type = Q;
    if (-1 == send(sockfd, msg, sizeof(msg_t), 0))
    {
        perror("send error");
        exit(-1);
    }
    close(sockfd);
    printf("欢迎下次使用基于TCP的在线词典系统...\n");
    exit(-1);
}
int regist_user(msg_t *msg, int sockfd)
{
    memset(msg, 0, sizeof(msg_t));
    msg->type = R;
    printf("[注册]请输入用户名:");
    scanf("%s", msg->name);
    printf("[注册]请输入密码:");
    scanf("%s", msg->data);
    // printf("[regist_user]msg.type = %d\n", msg->type);
    // printf("[regist_user]msg.name = %s\n", msg->name);
    // printf("[regist_user]msg.data = %s\n", msg->data);
    if (-1 == send(sockfd, msg, sizeof(msg_t), 0))
    {
        perror("send error");
        exit(-1);
    }
    // printf("[regist_send]msg.type = %d\n", msg->type);
    // printf("[regist_send]msg.name = %s\n", msg->name);
    // printf("[regist_send]msg.data = %s\n", msg->data);
    memset(msg, 0, sizeof(msg));
    if (-1 == recv(sockfd, msg, sizeof(msg_t), 0))
    {
        perror("recv error");
        exit(-1);
    }
    // printf("[regist_recv]msg.type = %d\n", msg->type);
    // printf("[regist_recv]msg.name = %s\n", msg->name);
    // printf("[regist_recv]msg.data = %s\n", msg->data);
    if (strncmp(msg->data, "OK", 3) == 0)
    {
        printf("注册成功...\n");
        return 1;
    }
    printf("用户名已存在,注册失败...\n");
    return 0;
}
int login_user(msg_t *msg, int sockfd, sqlite3 *my_db)
{
    memset(msg, 0, sizeof(msg_t));
    msg->type = L;
    printf("[登录]请输入用户名:");
    scanf("%s", msg->name);
    printf("[登录]请输入密码:");
    scanf("%s", msg->data);
    if (-1 == send(sockfd, msg, sizeof(msg_t), 0))
    {
        perror("send error");
        exit(-1);
    }
    memset(msg, 0, sizeof(msg));
    if (-1 == recv(sockfd, msg, sizeof(msg_t), 0))
    {
        perror("recv error");
        exit(-1);
    }
    int choose = 0;
    if (strncmp(msg->data, "OK", 3) == 0)
    {
        printf("登录成功...\n");
        return 1;
    }
    printf("用户名或密码错误...\n");
    return 0;
}
// int exit_search(msg_t *msg, int sockfd)
// {
//     return 0;
// }
int search_world(msg_t *msg, int sockfd, sqlite3 *my_db)
{
}

int check_user(msg_t msg, int sockfd)
{
    printf("[check_user_send]msg.type = %d\n", msg.type);
    printf("[check_user_send]msg.name = %s\n", msg.name);
    printf("[check_user_send]msg.data = %s\n", msg.data);
    if (-1 == send(sockfd, &msg, sizeof(msg), 0))
    {
        perror("send error");
        exit(-1);
    }
    memset(&msg, 0, sizeof(msg));
    if (-1 == recv(sockfd, &msg, sizeof(msg), 0))
    {
        perror("recv error");
        exit(-1);
    }
    printf("[check_user_recv]msg.type = %d\n", msg.type);
    printf("[check_user_recv]msg.name = %s\n", msg.name);
    printf("[check_user_recv]msg.data = %s\n", msg.data);
    if (strcmp(msg.data, "user already exit,regist fail") == 0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

运行结果图

 

3.4 完成查询单词功能(search)

单词文件

链接:https://pan.baidu.com/s/17qgZZpO7YyyQ0pCLYclg8A 
提取码:关注收藏后,私信获取

service.c

client.c

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1901223.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习】图形模型基础(5):线性回归模型第四部分:预测与贝叶斯推断

1.引言 贝叶斯推断超越了传统估计方法&#xff0c;它包含三个关键步骤&#xff1a;结合数据和模型形成后验分布&#xff0c;通过模拟传播不确定性&#xff0c;以及利用先验分布整合额外信息。本文将通过实际案例阐释这些步骤&#xff0c;展示它们在预测和推断中的挑战和应用。…

编程上下文Context及其实现原理

编程上下文Context及其实现原理 author:shengfq date:2024-07-06 title:编程上下文Context及其实现原理 category:编程思想1.编程中的上下文Context是指什么? 在编程和软件工程领域&#xff0c;“上下文”&#xff08;Context&#xff09;是一个多义词&#xff0c;其含义可以…

产品经理-​合作的6类干系人(8)

在一个项目中&#xff0c;产品经理并不是一个人在战斗&#xff0c;而是在很多同事的配合下共同完成项目。那产品经理到底要和哪些角色配合&#xff0c;一起完成项目呢 中间的产品经理是一个项目的驱动者。而产品经理的前方是“Boss/Leader”&#xff0c;也就是创业团队中公司的…

地级市数字经济指数、互联网用户数、数字金融普惠指数

2000-2022年地级市数字经济指数&#xff08;含控制变量&#xff09; 目录 数字经济如何改善环境污染 一、引言 二、文献综述 三、实证模型 四、数据来源 五、程序代码 六、运行结果 数字经济如何改善环境污染 摘要&#xff1a; 本论文旨在探讨数字经济对环境污染的改善作…

三级_网络技术_04_中小型网络系统总体规划与设计

1.下列关于路由器技术特征的描述中&#xff0c;正确的是()。 吞吐量是指路由器的路由表容量 背板能力决定了路由器的吞吐量 语音、视频业务对延时抖动要求较低 突发处理能力是以最小帧间隔值来衡量的 2.下列关于路由器技术特征的描述中&#xff0c;正确的是()。 路由器的…

Matlab中collectPlaneWave函数的应用

查看文档如下&#xff1a; 可以看出最多5个参数&#xff0c;分别是阵列对象&#xff0c;信号幅度&#xff0c;入射角度&#xff0c;信号频率&#xff0c;光速。 在下面的代码中&#xff0c;我们先创建一个3阵元的阵列&#xff0c;位置为&#xff1a;&#xff08;-1,0,0&#x…

JavaWeb----JSPJSTL

目录 JSP显隐注释在JSP中写java程序JSP的指令标签JSP中的四大域对象简易版用户登录EL表达式 JSTL条件动作标签if标签 choose\when\otherwise标签迭代标签格式化动作标签 用户登录实例查看是否安装了mysql用户登录界面后台实现 JSP JSP全名是Java Server Pages&#xff0c;它是建…

【后端面试题】【中间件】【NoSQL】MongoDB查询优化3(拆分、嵌入文档,操作系统)

拆分大文档 很常见的一种优化手段&#xff0c;在一些特定的业务场景中&#xff0c;会有一些很大的文档&#xff0c;这些文档有很多字段&#xff0c;而且有一些特定的字段还特别的大。可以考虑拆分这些文档 大文档对MongoDB的性能影响还是很大的&#xff0c;就我个人经验而言&…

常见算法和Lambda

常见算法和Lambda 文章目录 常见算法和Lambda常见算法查找算法基本查找&#xff08;顺序查找&#xff09;二分查找/折半查找插值查找斐波那契查找分块查找扩展的分块查找&#xff08;无规律的数据&#xff09; 常见排序算法冒泡排序选择排序插入排序快速排序递归快速排序 Array…

在Apache HTTP服务器上配置 TLS加密

安装mod_ssl软件包 [rootlocalhost conf.d]# dnf install mod_ssl -y此时查看监听端口多了一个443端口 自己构造证书 [rootlocalhost conf.d]# cd /etc/pki/tls/certs/ [rootlocalhost certs]# openssl genrsa > jiami.key [rootlocalhost certs]# openssl req -utf8 -n…

Pycharm远程连接GPU(内容:下载安装Pycharm、GPU租借、配置SSH、将代码同步到镜像、命令行操控远程镜像、配置远程GPU解释器)

目录 windows下载安装pycharmGPU租借网站AutoDlfeaturize好易智算 GPU租借GPU选择选择镜像充值 然后创建镜像创建成功 复制SSH登录信息 远程进入镜像 在Pycharm中进行ssh连接新建SFTP配置SSH复制ssh根据复制的信息填写ssh配置测试连接 将代码同步到远程镜像上设置mappings将本地…

React 省市查询组件完整代码

目录 一、地区文件 二、Antd配合使用 三、实现效果 一、地区文件 下载地址&#xff1a;全国省市区数据_JSON格式_SQL格式 export const chinaArea {0: {1: 北京,2: 天津,3: 河北省,4: 山西省,5: 内蒙古自治区,6: 辽宁省,7: 吉林省,8: 黑龙江省,9: 上海,10: 江苏省,11: 浙…

计算机出现找不到msvcp140.dll无法继续执行代码怎么办?推荐7个有效解决方法

在日常使用电脑过程中会经常遇到各式各样的问题&#xff0c;比如msvcp140.dll丢失或找不到msvcp140.dll文件是最常见的问题之一&#xff0c;那么遇到这个问题要怎么解决呢&#xff1f;msvcp140.dll到底是什么&#xff1f;为什么会出现msvcp140.dll丢失问题&#xff1f;今天给大…

原生事件监听及组件内置事件处理

监听事件 我们可以使用 v-on 指令 (简写为 ) 来监听 DOM 事件&#xff0c;并在事件触发时执行对应的 JavaScript。用法&#xff1a;v-on:click“handler” 或 click“handler”。 事件处理器 (handler) 的值可以是&#xff1a; 内联事件处理器&#xff1a;事件被触发时执行的…

《QT从基础到进阶·四十三》QPlugin插件多线程问题和只有插件dll没有头文件和lib文件时调用插件中的方法

1、插件和多线程问题&#xff1a; 创建插件对象不能放到多线程执行&#xff0c;不然报错&#xff1a;ASSERT failure in QWidget: "Widgets must be created in the GUlthread. //不能放在多线程执行 QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName))…

单选多选提交问卷,代码示例

&#xff45;&#xff4c;&#xff45;&#xff4d;&#xff45;&#xff4e;&#xff54;中 需要对接口返回的数据进行分析。多选问题使用checkbox&#xff0c;单选题使用radio。 多选时可以绑定&#xff4d;&#xff49;&#xff4e;&#xff0f;&#xff4d;&#xff41;&am…

Transformer前置知识:Seq2Seq模型

Seq2Seq model Seq2Seq&#xff08;Sequence to Sequence&#xff09;模型是一类用于将一个序列转换为另一个序列的深度学习模型&#xff0c;广泛应用于自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;如机器翻译、文本摘要、对话生成等。Seq2Seq模型由编码器&#…

搭建互联网医院实战:从源码到在线问诊APP的全流程开发

今天&#xff0c;笔者将讲述在线问诊APP的全流程开发&#xff0c;帮助开发者理解和掌握搭建互联网医院的核心技术和步骤。 一、需求分析与设计 需求分析包括明确目标用户、功能需求、性能需求等。设计阶段则包括系统架构设计、数据库设计和前后端界面设计等。 1.目标用户&…

统计是一门艺术(非参数假设检验)

1.定义 当总体分布未知&#xff0c;那么就需要一种与分布具体数学形式无关的统计推断方法&#xff0c;称为非参数方法 只能利用样本中的一般信息包括位置和次序关系等 稳健性强 2.符号检验 考虑问题&#xff1a; 小样本情况&#xff1a; 以概率为1/2的二项分布是对称的 两…

ASP.NET Core----基础学习01----HelloWorld---创建Blank空项目

文章目录 1. 创建新项目--方式一&#xff1a; blank2. 程序各文件介绍&#xff08;Project name &#xff1a;ASP.Net_Blank&#xff09;&#xff08;1&#xff09;launchSettings.json 启动方式的配置文件&#xff08;2&#xff09;appsettings.json 基础配置file参数的读取&a…