使用C语言实现网上词典

功能:

  1. 客户端每次连接服务器时,都需要登陆或注册对应的账号和密码;
  2. 如果客户端没有账号,则应该注册账号和密码;
  3. 客户端登陆成功后, 应该具有检索单词,查看历史的功能;
    4.可以根据自己情况自行添加其他功能;

.h文件

#ifndef _HEAD_H_
#define _HEAD_H_
enum un
{
    regi,
    login,
    quit,
};
//链表节点结构体:
typedef struct node
{
    struct sockaddr_in addr; //data   memcmp
    struct node *next;
} link_t;

//消息对应的结构体(同一个协议)
typedef struct msg_t
{
    int choose;
    char name[128];      //用户名
    char password[128]; //消息正文
} MSG_t;
#endif

客户端

client.c
void show(void)
{
    printf("***************************************\n");
    printf("***************0:register**************\n");
    printf("***************1:login*****************\n");
}
void show2(void)
{
    printf("***************2:Quit*****************\n");
    printf("***************3:History******************\n");
    printf("***************4:Quire******************\n");
}
int creat_socket(void)
{
    int sockec;
    if ((sockec = socket(AF_INET, SOCK_STREAM, 0)) < 0) //TCP向下默认匹配ip协议
    {
        perror("socket err");
        return -1;
    }
    return sockec;
}

int main(int argc, char const *argv[])
{
    int n;
    char buf[128] = {0};
    char file[128] = {0};
    char name[128] = {0};
    char password[128] = {0};
    int choose;
    //创建套接字
    int sockec, ret;
    sockec = creat_socket();
    printf("%d\n", sockec);
    //指定服务器的信息
    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(atoi(argv[1]));
    saddr.sin_addr.s_addr = INADDR_ANY;
    // saddr.sin_addr.s_addr = inet_addr("192.168.50.194");
    //请求连接服务器
    if (connect(sockec, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) //sockets只能用于连接
    {
        perror("connect err");
        return -1;
    }
    else
        printf("con succ\n");
    //创建身份结构体
    MSG_t msg;
    while (1)
    {
        show();
        printf("please choose\n");
        scanf("%d", &choose);
        msg.choose = choose;
        printf("input name\n");
        scanf("%s", name);
        strcpy(msg.name, name);
        printf("input password\n");
        scanf("%s", password);
        strcpy(msg.password, password);
        send(sockec, &msg, sizeof(msg), 0); //发送信息
        if (choose == 0)
        {
            memset(buf, 0, sizeof(buf));
            ret = recv(sockec, buf, 256, 0); //默认阻塞
            if (ret < 0)
            {
                perror("recv err");
                return -1;
            }
            else if (ret == 0)
            {

                printf("dis connect\n");
                break;
            }
            else
            {
                printf("%s\n", buf);
                if (strncmp(buf, "register failure", sizeof(buf)) == 0)
                    printf("register failure\n");
                else
                {
                    printf("%s\n", buf);
                }
            }
        }
        else if (choose == 1)
        {
            memset(buf, 0, sizeof(buf));
            ret = recv(sockec, buf, 256, 0); //默认阻塞
            if (ret < 0)
            {
                perror("recv err");
                return -1;
            }
            else if (ret == 0)
            {

                printf("dis connect\n");
                break;
            }
            else
            {
                if (strncmp(buf, "login failure", sizeof(buf)) == 0)
                    printf("login failure\n");
                else
                {
                    //登录成功
                    printf("%s\n", buf);
                    while (1)
                    {
                        memset(buf, 0, sizeof(buf));
                        show2();
                        printf("please choose\n");
                        scanf("%d", &n);
                        if (n == 2)
                        {
                            strcpy(buf, "Quit");
                            send(sockec, buf, sizeof(buf), 0); //发送信息
                        }
                        else if (n == 3)
                        {
                            strcpy(buf, "History");
                            send(sockec, buf, sizeof(buf), 0); //发送信息
                            while (1)
                            {
                                memset(buf, 0, sizeof(buf));
                                ret = recv(sockec, buf, 256, 0);   //默认阻塞
                                if (ret < 0)
                                {
                                    perror("recv err");
                                    return -1;
                                }
                                else if (ret == 0)
                                {

                                    printf("dis connect\n");
                                    break;
                                }
                                else
                                {
                                    if (strcmp(buf, "over") == 0)
                                    {
                                        break;
                                    }
                                    printf("%s\n", buf);
                                }
                            }

                        }
                        else if (n == 4)
                        {
                            strcpy(buf, "Quire");
                            send(sockec, buf, sizeof(buf), 0); //发送信息
                            while (1)
                            {
                                memset(buf, 0, sizeof(buf));
                                printf("please input word(#:quit):\n");
                                scanf("%s", buf);
                                send(sockec, buf, sizeof(buf), 0); //发送信息
                                ret = recv(sockec, buf, 256, 0);   //默认阻塞
                                if (ret < 0)
                                {
                                    perror("recv err");
                                    return -1;
                                }
                                else if (ret == 0)
                                {

                                    printf("dis connect\n");
                                    break;
                                }
                                else
                                {
                                    if (strcmp(buf, "#") == 0)
                                    {
                                        printf("without this word\n");
                                        continue;
                                    }
                                    printf("%s\n", buf);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    close(sockec);

    return 0;
}

服务端

char sql[128] = {0};
int callback(void *buf, int num, char **value, char **name);
void client_regi(int sockfd, MSG_t msg, struct sockaddr_in caddr);
int client_login(int sockfd, MSG_t msg, struct sockaddr_in caddr);
sqlite3 *db;

void handler(int sig)
{
    waitpid(-1, NULL, WNOHANG);
}
int main(int argc, char const *argv[])
{
    pid_t pid;
    int acceptfd;
    char buf[128] = {0};
    int ret, ret1;
    char times[128] = {0};
    char *errmsg = NULL;
    char **result = NULL;
    int row, column;
    //获取时间
    time_t timep;
    struct tm *p;
    time(&timep);
    p = gmtime(&timep);
    // 1.创建流式套接字(socket)-----------------------------》有手机
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("sock err");
        return -1;
    }
    printf("sockfd:%d\n", sockfd);
    // 2.指定网络信息-----------------------------------------------》有号码
    struct sockaddr_in saddr, caddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(atoi(argv[1]));
    //saddr.sin_addr.s_addr = inet_addr("0.0.0.0");
    saddr.sin_addr.s_addr = INADDR_ANY;
    //INADDR_ANY:0.0.0.0
    // 3.绑定套接字(bind)--------------------------------------》绑定手机
    if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
    {
        perror("bind err");
        return -1;
    }
    printf("bind ok\n");
    // 4.监听套接字(listen)-------------------------------------》待机
    //将主动套接字变成被动套接字
    if (listen(sockfd, 6) < 0)
    {
        perror("listen err");
        return -1;
    }
    printf("listen ok\n");
    // 5.接收客户端请求(accept)
    int len = sizeof(caddr);
    MSG_t msg;
    while (1)
    {
        acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);
        if (acceptfd < 0)
        {
            perror("accept err");
            return -1;
        }
        printf("accept ok\n");
        printf("ip:%s port:%d\n", inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
        pid = fork();
        if (pid < 0)
        {
            perror("fork err");
            return -1;
        }
        else if (pid == 0)
        {
            //子进程
            while (1)
            { // 6.发送、接收消息(send、recv)-----------------------》通话
                ret = recv(acceptfd, &msg, sizeof(msg), 0);
                if (ret < 0)
                {
                    perror("recv errr");
                    break;
                }
                else if (ret == 0)
                {
                    printf("client exit\n");
                    break;
                }
                else
                {
                    //选择类型
                    printf("type:%d\n", msg.choose);
                    switch (msg.choose)
                    {
                    case regi:
                        client_regi(acceptfd, msg, caddr);
                        break;
                    case login:
                        ret1 = client_login(acceptfd, msg, caddr);
                        if (ret1 == 0)
                        {
                            ret = recv(acceptfd, buf, sizeof(buf), 0);
                            if (ret < 0)
                            {
                                perror("recv errr");
                                break;
                            }
                            else if (ret == 0)
                            {
                                printf("client exit\n");
                                break;
                            }
                            else
                            {
                                printf("%s\n", buf);
                                if (strcmp(buf, "Quire") == 0)
                                {
                                    printf("start quire\n");
                                    while (1)
                                    {
                                        ret = recv(acceptfd, buf, sizeof(buf), 0);
                                        if (ret < 0)
                                        {
                                            perror("recv errr");
                                            break;
                                        }
                                        else if (ret == 0)
                                        {
                                            printf("client exit\n");
                                            break;
                                        }
                                        else
                                        {
                                            printf("%s\n", buf);
                                            // if (strcmp(buf, "#") == 0)
                                            //     break;
                                            sprintf(sql, "select * from  words where wordname=\"%s\";", buf);
                                            sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);
                                            printf("row:%d column:%d\n", row, column);
                                            if (row == 0)
                                            {
                                                strcpy(buf, "#");
                                                send(acceptfd, buf, sizeof(buf), 0);
                                                continue;
                                            }
                                            else
                                            {
                                                sprintf(times, "%d-%d-%d %d:%d:%d ", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday, p->tm_hour + 8, p->tm_min, p->tm_sec);
                                                printf("%s\n", times);

                                                sprintf(sql, "insert into sit values(\"%s\",\"%s\");", buf, times);
                                                //插入数据
                                                if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
                                                {
                                                    fprintf(stderr, "create stu err %s\n", errmsg);
                                                    return -1;
                                                }
                                            }
                                            int k = 0;
                                            for (int i = 0; i <= row; i++)
                                            {
                                                for (int j = 0; j < column; j++)
                                                    printf("%s ", result[k++]);
                                                putchar(10);
                                            }
                                            strcpy(buf, result[5]);
                                            send(acceptfd, buf, sizeof(buf), 0);
                                        }
                                    }
                                }
                                else if (strcmp(buf, "History") == 0)
                                {
                                    sqlite3_get_table(db, "select * from  sit;", &result, &row, &column, &errmsg);
                                    printf("row:%d column:%d\n", row, column);
                                    int k = 0;
                                    for (int i = 0; i <= row; i++)
                                    {
                                        memset(buf, 0, sizeof(buf));
                                        for (int j = 0; j < 2; j++)
                                        {

                                            //printf("%s ", result[k++]);
                                            strcat(buf, result[k++]);
                                        }
                                        printf("%d\n", k);

                                        printf("%s\n", buf);
                                        send(acceptfd, buf, sizeof(buf), 0);
                                        // putchar(10);
                                    }
                                    strcpy(buf, "over");
                                    send(acceptfd, buf, sizeof(buf), 0);
                                }
                                break;
                            }
                        }
                        else
                        {
                            printf("login failure\n");
                        }

                        break;
                        // case quit:
                        //     client_quit(acceptfd, msg, caddr);
                        //     break;

                    default:
                        break;
                    }
                }
            }
            close(acceptfd);
            exit(0);
        }
        else
        {
            close(acceptfd);
            signal(SIGCHLD, handler);
        }
    }
    //recv(acceptfd, buf, 128, 0);

    // 7.关闭套接字(close)-------------------------------------》挂电话
    close(sockfd);

    return 0;
}
void client_regi(int sockfd, MSG_t msg, struct sockaddr_in caddr)
{
    //char buf[128] = "register success";
    char text[128] = {0};
    sprintf(text, "%s register...", msg.name);
    //将新登录的用户信息添加到数据库中并且通知其他在线用户
    // 打开数据库
    if (sqlite3_open("./yun.db", &db) != SQLITE_OK)
    {
        fprintf(stderr, "open yun err %s", sqlite3_errmsg(db));
        //return -1;
    }
    //操作数据库
    char *errmsg = NULL;
    sprintf(sql, "select * from  stu where name=\"%s\"", msg.name);

    if (sqlite3_exec(db, sql, callback, "hello", &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "select stu err %s\n", errmsg);
        //return -1;
    }
    else
    {
        sprintf(sql, "insert into stu values(\"%s\",\"%s\");", msg.name, msg.password);
        if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
        {
            fprintf(stderr, "create stu err %s\n", errmsg);
            //return -1;
        }
        else
        {
            printf("%s\n", text);
            send(sockfd, text, sizeof(msg), 0);
        }
    }
    return;
}
int client_login(int sockfd, MSG_t msg, struct sockaddr_in caddr)
{
    int ret;
    char text[128] = {0};
    sprintf(text, "%s login...", msg.name);
    //printf("%s\n", text);
    //将新登录的用户信息添加到数据库中并且通知其他在线用户
    //sqlite3 *db;
    // 打开数据库
    if (sqlite3_open("./yun.db", &db) != SQLITE_OK)
    {
        fprintf(stderr, "open yun err %s", sqlite3_errmsg(db));
        return -1; //打开失败
    }
    //操作数据库
    char *errmsg = NULL;
    char **result = NULL;
    int row, column;
    sprintf(sql, "select * from  stu where name=\"%s\";", msg.name);
    sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);
    printf("row:%d column:%d\n", row, column);
    if (row == 0)
    {
        memset(text, 0, sizeof(text));
        strcpy(text, "login failure");
    }
    send(sockfd, text, sizeof(text), 0);
    return 0;
}
int callback(void *buf, int num, char **value, char **name)
{
    //buf
    printf("%s\n", (char *)buf);
    //num:列的数量
    //value:值
    //name:列名
    for (int i = 0; i < num; i++)
        printf("%s ", name[i]);
    for (int i = 0; i < num; i++)
        printf("%s ", value[i]);
    putchar(10);

    //一定要加,不然会认为回调出错了
    return 0;
}

将单词导入数据库


//int callback(void *buf, int num, char **value, char **name);

int main(int argc, char const *argv[])
{
    sqlite3 *db;
    // 打开/创建数据库
    if (sqlite3_open("./yun.db", &db) != SQLITE_OK)
    {
        fprintf(stderr, "open stu err %s", sqlite3_errmsg(db));
        return -1;
    }
    //操作数据库
    char *errmsg = NULL;
    //创建words表
    if (sqlite3_exec(db, "create table words(id int,wordname char,express char);", NULL, NULL, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "create stu err %s\n", errmsg);
        //return -1;
    }
    printf("words table success\n");
    //创建stu表
    if (sqlite3_exec(db, "create table stu(name char,password char);", NULL, NULL, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "create stu err %s\n", errmsg);
        //return -1;
    }
    printf("stu table success\n");
    //创建his表
    if (sqlite3_exec(db, "create table sit(word char,time char);", NULL, NULL, &errmsg) != SQLITE_OK)
    {
        fprintf(stderr, "create sit err %s\n", errmsg);
        //return -1;
    }
    printf("his table success\n");
    char buf[1000] = {0};
    char word[200] = {0};
    char sql[200] = {0};
    char tail[1000] = {0};
    char *n = NULL;
    //打开文件
    FILE *fp;
    int j, i, id = 1;
    fp = fopen("./dict.txt", "r");
    if (fp == NULL)
    {
        perror("open err");
        return -1;
    }
    printf("open ok\n");

    while (1)
    {
        i = 0;
        n = fgets(buf, sizeof(buf), fp);
        if (n == NULL)
            break;
        while (1)
        {
            if (buf[i] == ' ')
                break;

            i++;
        }
        for (j = 0; j < i; j++)
        {
            word[j] = buf[j];
        }
        while (1)
        {
            if (buf[i] == ' ')
                break;
            i++;
        }
        strcpy(tail, buf + i);
        tail[sizeof(tail) - 1] = '\0';
        printf("%d ", id);
        printf("%s %s\n", word, tail);
        sprintf(sql, "insert into words values (%d,\"%s\",\"%s\");", id, word, tail);
        if (sqlite3_exec(db, sql, NULL, NULL, &errmsg) != SQLITE_OK)
        {
            fprintf(stderr, "create stu err %s\n", errmsg);
            return -1;
        }
        else
        {
            id++;
        }
        memset(buf, 0, sizeof(buf));
        memset(tail, 0, sizeof(tail));
        memset(word, 0, sizeof(word));
    }

    sqlite3_close(db);
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值