网络编程练手小项目---英英词典

本文介绍了一个使用TCP/IP协议、C语言实现的网络编程项目——英英词典。该应用包括注册、登录、查询单词和查看历史记录等功能,通过服务器的IO多路复用实现并发处理。用户信息存储在数据库中,登录状态在结构体中维护。文章还分享了项目代码,适合初学者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现的功能

注册

登录

查询单词

查询历史记录

大概思路

搭建tcp服务器,通过IO多路复用实现并发(伪并发)。注册:接收到客户端发来的数据,建立一张用户表,将注册信息存储到数据库的用户表中,不过存入之前要判断是否重名  数据可以是一个结构体  可以设置结构中的一个成员为客户端发送过来的指令 客户端根据指令判断是注册 登录 等等。登录同理,不过这时候服务器对数据库表的操作为查询,有注册成功 没有则做其他处理。登录成功后修改登录状态为在线  这个标志位同样存储在结构体中。查询单词 历史记录等同样是对数据库进行查找、插入操作等  这里就不作过多赘述。

下面直接将这个练手的小项目的详细代码分享给大家  希望能帮助到刚入门的你  博客写的不是很规范将就看看吧  内容中若有错误的地方还请指正

定义的结构体:

typedef struct message_user{
    char name[20];
    char passwd[20];
    char wordname[20];
    char meaning[128];
    int flags;//判断发送的指令
    int states;//用户是否在线
    int ifuser;//用户名是否存在
    int loginflags;// 1成功 2 密码错误 3 用户名不存在
    int ifinsearch;//是否查找到对应单词 0没有 1查到
    int histroyflags;//1 byuser 2 bywordname
    char result[48][128];//历史记录
    int num;//查询的记录条数
    int column;//字段个数
}info;

注册

int Register(int connfd,sqlite3 *db)
{
    char buf[128] = {0};
            int ret = sqlite3_open("wmk.db",&db);
            if(ret != SQLITE_OK)
            {
                printf("%s\n",sqlite3_errmsg(db));
                return -1;
            }
            
            strcpy(buf,"create table if not exists user(name char[10],passwd char[20]);");
            char *errmsg = NULL;
            ret = sqlite3_exec(db,buf,NULL,NULL,&errmsg);
            if(ret != SQLITE_OK)
            {
                printf("%s\n",errmsg);
                return -1;
            }
b: bzero(buf,sizeof(buf));
            sprintf(buf,"select * from user where name='%s';",message.name);
            char **result;
            int num = 0;
            int column = 0;
            if(sqlite3_get_table(db,buf,&result,&num,&column,&errmsg) != SQLITE_OK)
            {
                printf("%s\n",errmsg);
                return -1;
            }
            
            if(num > 0)
            {
                message.ifuser = 1;//用户名已存在
            }
            else
            {
                message.ifuser = 0;//用户名不存在
                bzero(buf,sizeof(buf));
                sprintf(buf,"insert into user values('%s','%s');",message.name,message.passwd);
                if(sqlite3_exec(db,buf,NULL,NULL,&errmsg) < 0)
                {
                    printf("%s\n",errmsg);
                    return -1;
                }
            }
            ret = write(connfd,&message,sizeof(message));
            if(ret < 0)
            {
                perror("write");
                return -1;
            }

            if(message.ifuser == 1)
            {
                ret = read(connfd,&message,sizeof(message));
                goto b;

            }
            

    printf("注册\n");
    return 0;

}

登录

int Login(int connfd,sqlite3 *db)
{
    char buf[128] = {0};
    int ret = sqlite3_open("wmk.db",&db);
    if(ret != SQLITE_OK)
    {
        printf("%s\n",sqlite3_errmsg(db));
        return -1;

    }
a: sprintf(buf,"select * from user where name='%s' and passwd='%s';",message.name,message.passwd);
    char *errmsg = NULL;
    char **result;
    int num = 0;
    int column = 0;
    ret = sqlite3_get_table(db,buf,&result,&num,&column,&errmsg);
    if(ret != SQLITE_OK)
    {
        printf("%s\n",errmsg);
        return -1;
    }
    if(num)
    {
        message.loginflags = 1;
        message.states = 1;//表示在线
        //用户名存在且密码正确
        if(write(connfd,&message,sizeof(message)) < 0)
        {
            perror("write");
            return -1;
        }
    }
    else
    {
        num = 0;
        bzero(buf,sizeof(buf));
        sprintf(buf,"select *from user where name='%s';",message.name);
        ret =sqlite3_get_table(db,buf,&result,&num,&column,&errmsg);
        printf("%d\n",ret);
        if(ret != SQLITE_OK)
        {
            printf("%s\n",errmsg);
            return -1;
        }

        //用户名存在密码错误
        if(num)
        {
            message.loginflags = 2;
            if(write(connfd,&message,sizeof(message)) < 0)
            {
                perror("write");
                return -1;
            }

            if(read(connfd,&message,sizeof(message)) < 0)
            {
                perror("read");
                return -1;
            }
            goto a;
        }
        else
        {
           // 用户名不存在
            message.loginflags = 3;
            if(write(connfd,&message,sizeof(message)) < 0)
            {
                perror("write");
                return -1;
            }
            if(read(connfd,&message,sizeof(message)) < 0)
            {
                perror("write");
                return -1;
            }
            goto a;
        }
    }

    printf("登陆\n");
    return 0;
}

查询单词

int Insearch(int connfd,sqlite3 *db)
{
    
    if(message.states != 1)
    {
        if(write(connfd,&message,sizeof(message)) < 0)
        {
            perror("write");
            return -1;
        }
        return 0;
    }
    
    char buf[128] = {0};
    char *errmsg = NULL;
    char **result;
    int num = 0;
    int column = 0;
    int ret = sqlite3_open("wmk.db",&db);
    if(ret != SQLITE_OK)
    {
        sqlite3_errmsg(db);
        return -1;
    }
    strcpy(buf,"create table if not exists word(word char[128],meaning char[512]);");
    ret = sqlite3_exec(db,buf,NULL,NULL,&errmsg);
    if(ret != SQLITE_OK)
    {
        printf("%s\n",errmsg);
        return -1;
    }

    bzero(buf,sizeof(buf));
    strcpy(buf,"create table if not exists record(name char[20],time char[128]);");
    ret = sqlite3_exec(db,buf,NULL,NULL,&errmsg);
    if(ret != SQLITE_OK)
    {
        printf("%s\n",errmsg);
        return -1;
    }


    bzero(buf,sizeof(buf));
    strcpy(buf,"create table if not exists wrecord(wordname char[20],time char[128]);");
    ret = sqlite3_exec(db,buf,NULL,NULL,&errmsg);
    if(ret != SQLITE_OK)
    {
        printf("%s\n",errmsg);
        return -1;
    }


    bzero(buf,sizeof(buf));
    sprintf(buf,"select * from word where word='%s';",message.wordname);//查找单词
    ret = sqlite3_get_table(db,buf,&result,&num,&column,&errmsg);
    if(ret != SQLITE_OK)
    {
        printf("%s\n",errmsg);
        return -1;
    }
    if(num == 0)
    {
        message.ifinsearch = 0;
        if(write(connfd,&message,sizeof(message)) < 0 )
        {
            perror("write");
            return -1;
        }
    }
    else
    {
        bzero(buf,sizeof(buf));
        time_t t;
        time(&t);
        message.ifinsearch = 1;//查询到单词
        strcpy(message.meaning,result[3]);
        if(write(connfd,&message,sizeof(message)) < 0)
        {
            perror("write");
            return -1;
        }
        sprintf(buf,"insert into record values('%s','%s');",message.name,ctime(&t));
        ret = sqlite3_exec(db,buf,NULL,NULL,&errmsg);//将查询用户记录到单词用户表中,记录时间
        if(ret != SQLITE_OK)
        {
            printf("%s\n",errmsg);
            return -1;
        }

        bzero(buf,sizeof(buf)) ;
        sprintf(buf,"insert into wrecord values('%s','%s');",message.wordname,ctime(&t));
        ret = sqlite3_exec(db,buf,NULL,NULL,&errmsg);//将查询记录插入到单词记录表中 记录当前时间
        if(ret != SQLITE_OK)
        {
            printf("%s\n",errmsg);
            return -1;
        }

        
    }

    printf("查询单词\n");
    return 0;
}

历史记录(查询的时候插入对应的表中  只需将表中的数据打印出来)

int Histroy_r(int connfd,sqlite3 *db)
{
    char **result;
    char *errmsg = NULL;
    int num = 0;
    int column = 0;
    char buf[128] = {0};
    int ret = 0;
    ret = sqlite3_open("wmk.db",&db);
    if(ret != SQLITE_OK)
    {
        sqlite3_errmsg(db);
        return -1;
    }
    if(message.histroyflags == 1)//by user
    {
        strcpy(buf,"select * from record;");
       ret = sqlite3_get_table(db,buf,&result,&num,&column,&errmsg);
       if(ret != SQLITE_OK)
       {
           printf("%s\n",errmsg);
           return -1;
       }
       message.num = num;
       message.column = column;
       bzero(message.result,sizeof(message.result));
       for(int i = 0;i<num * column;i++)
       {
           strcpy(message.result[i],result[column + i]);
       }

       if(write(connfd,&message,sizeof(message)) < 0)
       {
           perror("write");
           return -1;
       }
      /*
       for(int i = 0;i < num;i++)
       {
            for(int j=0;j<column;j++,result++)
            {
                printf("%s",*(result + 2));
            }
            //puts("\n");
            
       }
       */
    }
    else
    {
        strcpy(buf,"select * from wrecord;");
       ret = sqlite3_get_table(db,buf,&result,&num,&column,&errmsg);
       if(ret != SQLITE_OK)
       {
           printf("%s\n",errmsg);
           return -1;
       }
       message.num = num;
       message.column = column;

       bzero(message.result,sizeof(message.result));
       for(int i = 0;i<num * column;i++)
       {
           strcpy(message.result[i],result[column + i]);
       }

       if(write(connfd,&message,sizeof(message)) < 0)
       {
           perror("write");
           return -1;
       }

    }
    printf("查找历史记录\n");
    return 0;
}

下面是整个客户端的代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <unistd.h>
typedef struct message_user{
    char name[20];
    char passwd[20];
    char wordname[20];
    char meaning[128];
    int flags;//判断发送的指令
    int states;//用户是否在线 0 out 1 online
    int ifuser;//判断注册是否重名
    int loginflags;// 1成功 2 密码错误 3 用户名不存在
    int ifinsearch;//是否查找到对应单词 0没有 1查到
    int histroyflags;//1 byuser 2 bywordname
    char result[48][128];//历史记录
    int num;//查询的记录条数
    int column;//字段个数
}info;
info message = {0};
int Register(int sockfd)
{
a:  printf("请输入用户名:\n");
    fgets(message.name,sizeof(message.name),stdin);
    message.name[strlen(message.name) - 1] = '\0';
    printf("%s\n",message.name);
    printf("请输入密码:\n");
    fgets(message.passwd,sizeof(message.passwd),stdin);
    message.passwd[strlen(message.passwd) - 1] = '\0';
    printf("%s\n",message.passwd);
    
    if(write(sockfd,&message,sizeof(message)) < 0)
    {
        perror("write");
        return -1;
    }

    if(read(sockfd,&message,sizeof(message)) < 0)
    {
        perror("read");
        return -1;
    }
    if(message.ifuser == 1)
    {
        printf("用户名已存在请重新输入\n");
        goto a;
    }
    else
    {
        printf("注册成功\n");
    }
    sleep(3);
    system("clear");

    return 0;
}
int Login(int sockfd)
{
b: printf("请输入用户名:\n");
    fgets(message.name,sizeof(message.name),stdin);
    message.name[strlen(message.name) - 1] = '\0';
c: printf("请输入密码:\n");
    fgets(message.passwd,sizeof(message.passwd),stdin);
    message.passwd[strlen(message.passwd) - 1] = '\0';
    if(write(sockfd,&message,sizeof(message)) < 0)
    {
        perror("write");
        return -1;
    }
    if(read(sockfd,&message,sizeof(message)) < 0)
    {
        perror("write");
        return -1;
    }
    switch(message.loginflags)
    {
        case 1:printf("登陆成功\n");sleep(3);break;
        case 2:
               {
                    printf("密码错误,请重新输入\n");
                    goto c;
                    break;
               }
        case 3:
               {
                   printf("用户名不存在,请重新输入\n");
                   goto b;
                   break;
               }
    }
    system("clear");
    return 0;

}
int Insearch(int sockfd)
{
    printf("请输入你要查询的单词:\n");
    fgets(message.wordname,sizeof(message),stdin);
    message.wordname[strlen(message.wordname) - 1] = '\0';

    if(write(sockfd,&message,sizeof(message)) < 0)
    {
        perror("write");
        return -1;
    }
    if(read(sockfd,&message,sizeof(message)) < 0)
    {
        perror("write");
        return -1;
    }
    if(message.states != 1)
    {
        printf("您还未登陆,请先登陆\n");
        message.flags = 2;
        Login(sockfd);
    }
    else
    {
        if(message.ifinsearch == 0)
        {
            printf("单词库没有此单词\n");
            sleep(3);
            system("clear");
        }
        else
        {
            printf("%s:%s\n",message.wordname,message.meaning);
            sleep(3);
            system("clear");
        }
    }
    return 0;

}
int Histroy_r(int sockfd)
{
d:
    if(message.states != 1)
    {
        message.flags = 2;
        printf("您还未登陆,请登陆\n");
        Login(sockfd);
    }
    else
    {
      
        int n = 0;
        printf("***1.by user***2.by wordname***\n");
        scanf("%d",&n);
        getchar();
        if(n==1)
        {
            message.histroyflags = 1;
            if(write(sockfd,&message,sizeof(message)) < 0)
            {
                perror("write");
                return -1;
            }
            if(read(sockfd,&message,sizeof(message)) < 0)
            {
                perror("write");
                return -1;
            }

            for(int i = 0;i < message.num;i++)
            {
                printf("%s 在 %s查看了单词\n",*(message.result + 2*i),*(message.result+(2*i + 1)));
            }
        }
        else if(n == 2)
        {
            message.histroyflags = 2;
            if(write(sockfd,&message,sizeof(message)) < 0)
            {
                perror("write");
                return -1;
            }
            if(read(sockfd,&message,sizeof(message)) < 0)
            {
                perror("write");
                return -1;
            }

            for(int i = 0;i < message.num;i++)
            {
                printf("%s 在 %s时被查询了\n",*(message.result + 2*i),*(message.result+(2*i + 1)));
            }

        }
        else
        {
            printf("输入错误,请重新输入\n");
            goto d;
        }
    }
    sleep(3);
    system("clear");
        return 0;
    
}
int main(int argc, char *argv[])
{ 
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        perror("sockfd");
        return -1;
    }

    printf("%d\n",sockfd);
    struct sockaddr_in saddr;
    bzero(&saddr,sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = inet_addr("192.168.153.128");
    saddr.sin_port  = htons(8888);
    int ret = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(ret < 0)
    {
        perror("connect");
        return -1;
    }
    printf("connect success\n");


    while(1)
    {
        printf("-------欢迎来到英英词典--------\n");
        printf("-----1.注册-----2.登陆-----3.查询单词-----4.查看历史记录-----\n");   
a:      scanf("%d",&message.flags);
        getchar();
        
        switch(message.flags)
        {
            case 1:Register(sockfd);break;
            case 2:Login(sockfd);break;
            case 3:Insearch(sockfd);break;
            case 4:Histroy_r(sockfd);break;
            default:printf("输入错误,请重新输入\n");goto a;
        }
       // printf("++%d\n",message.states);

    }




        

    
    close(sockfd);
    return 0;
} 

如果都看到这儿了希望不要吝啬您的赞噢  您的阅读点赞是我能够继续坚持的最大动力 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值