基于TCP的在线词典

此程序主要是利用tcp传输和sqlite3进行操作的。
程序执行过程部分截图
在这里插入图片描述
#在终端输入sqlite3,查看是否安装sqlite3,没有的话先安装sqlite3
sudo apt-get install sqlite3
sudo apt-get install libsqlite3-dev

打开数据库 sqlite3 my.db
然后在里面创建数据库
create table <table_name> (f1 type1, f2 type2,…);

需要在编译选项上加入-lsqlite3

server.c

#include <stdlib.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sqlite3.h>
#include <time.h>


#define  N  256 

typedef struct _msg
{
    char types;
    char name[N] ;
    char text[N] ;
}msg_t;

int login_callback(void*data,int num,char**value,char**name)
{
 //   int i;
    *(int * )data = 1 ;
#if 0
    if(*flag)
    {
        *flag = 0 ; 
        for(i=0;i<num;i++)
        {
            printf("%-10s",name[i]);
        }
        printf("\n");
    }
    for(i=0;i<num;i++)
    {
        printf("%-10s",value[i]);
    }
    printf("\n");

#endif

    return 0;
    
}
int process_register(int newsockfd,msg_t *msgp,sqlite3 *db)
{

    int ret;
    char *errmsg ;
    char sqlstr[N] = {0};
    sprintf(sqlstr,"insert into user values('%s','%s');",msgp->name,msgp->text);
    printf("sqlstr=%s\n",sqlstr) ;
    ret = sqlite3_exec(db,sqlstr,NULL,NULL,&errmsg);
    if(ret != SQLITE_OK)
    {
        printf("sqlite3_exec:%s\n",errmsg);
        strcpy(msgp->text,"用户名已经存在,请重新输入");
    }
    else 
    {
        strcpy(msgp->text,"注册成功");
    }

    ret = write(newsockfd,msgp,sizeof(msg_t));
    if(ret < 0)
    {
        perror("write"); 
        exit(-1);
    }
    return 0;
}
int process_login(int newsockfd,msg_t *msgp,sqlite3 *db)
{

    int ret;
    char *errmsg ;
    char sqlstr[N] = {0};
    int  login_flag = 0 ; 
    sprintf(sqlstr,"select * from user where name='%s' and passwd='%s';",msgp->name,msgp->text);
    printf("sqlstr=%s\n",sqlstr) ;
    ret = sqlite3_exec(db,sqlstr,login_callback,&login_flag,&errmsg);
    if(ret != SQLITE_OK)
    {
        printf("sqlite3_exec:%s\n",errmsg);
    }
    if(login_flag == 1)
    {
        strcpy(msgp->text,"登录成功");
    }
    else 
    {
        strcpy(msgp->text,"用户或密码错误,请重新输入");
    }
    ret = write(newsockfd,msgp,sizeof(msg_t));
    if(ret < 0)
    {
        perror("write"); 
        exit(-1);
    }
    return 0;
}
char * search_word(char *word)
{
    FILE * filp;
    static char line[N] ={0};
    char newword[100] ;
    strcpy(newword,word);
    strcat(newword," ");
    filp = fopen("./dict.txt","r");
    if(filp == NULL)
    {
        perror("fopen") ; 
        exit(-1);
    }
    while( fgets(line,N,filp) != NULL ) 
    {
        if( strncmp(newword,line,strlen(newword)) == 0 )  
        {
           printf("%s",line) ;
           return line ;
        }
        
    }
    return NULL;
}

char * get_localtime() 
{
    static char buf[100] ={0} ;
    time_t tm;
    time(&tm);
    strcpy(buf,ctime(&tm));
    buf[strlen(buf) -1] = 0 ;
    return buf;
}

int process_query(int newsockfd,msg_t *msgp,sqlite3 *db)
{

    int ret;
    char *retp;
    char *errmsg ;
    char sqlstr[N] = {0};
    int  login_flag = 0 ; 
    char word[100] = {0} ;
    strcpy(word,msgp->text);
    retp = search_word(word);
    if(retp == NULL)
    {
        strcpy(msgp->text,"要查找的单词不存在");
        ret = write(newsockfd,msgp,sizeof(msg_t));
        if(ret < 0)
        {
            perror("write"); 
            exit(-1);
        }
    }
    else 
    {
        strcpy(msgp->text,retp);
        sprintf(sqlstr,"insert into record values('%s','%s','%s');",msgp->name,word,get_localtime());
        printf("sqlstr=%s\n",sqlstr) ;
        ret = sqlite3_exec(db,sqlstr,NULL,NULL,&errmsg);
        if(ret != SQLITE_OK)
        {
            printf("sqlite3_exec:%s\n",errmsg);
        }
        ret = write(newsockfd,msgp,sizeof(msg_t));
        if(ret < 0)
        {
            perror("write"); 
            exit(-1);
        }
    }


    return 0;
}
int history_callback(void*data,int num,char**value,char**name)
{
    int i,ret;
    msg_t msg;
    char buf[256] ={0};
    
    int newsockfd = *(int * )data  ;
    memset(&msg,0,sizeof(msg_t));
    msg.types = 'H' ;
    for(i=0;i<num;i++)
    {
        sprintf(buf,"%-10s",value[i]);
        strcat(msg.text,buf);
    }
    ret = write(newsockfd,&msg,sizeof(msg_t));
    if(ret < 0)
    {
        perror("write"); 
        exit(-1);
    }
    return 0;
    
}
int process_history(int newsockfd,msg_t *msgp,sqlite3 *db)
{

    int ret;
    char *retp;
    char *errmsg ;
    char sqlstr[N] = {0};
    int  login_flag = 0 ; 
    sprintf(sqlstr,"select * from record where name='%s';",msgp->name);
    printf("sqlstr=%s\n",sqlstr) ;
    ret = sqlite3_exec(db,sqlstr,history_callback,&newsockfd,&errmsg);
    if(ret != SQLITE_OK)
    {
        printf("sqlite3_exec:%s\n",errmsg);
    }
    strcpy(msgp->text,"传输完成");
    ret = write(newsockfd,msgp,sizeof(msg_t));
    if(ret < 0)
    {
        perror("write"); 
        exit(-1);
    }


    return 0;
}
// ./a.out 192.168.1.57 8000
// argv[0] argv[1]       aegv[2]
int main(int argc, const char *argv[])
{
    sqlite3 *db  ;        /* OUT: SQLite db handle */
    int data = 1 ;
    int sockfd,ret,newsockfd;
    struct sockaddr_in myaddr,client;
    signal(SIGCHLD,SIG_IGN);
    msg_t msg;
    if(argc != 3)
    {
        printf("运行程序时带入ip 和 port\n");
        exit(-1);
    }
    socklen_t addrlen = sizeof(client);
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        perror("socket");
        exit(-1);
    }
    printf("sockfd=%d\n",sockfd);
    memset(&myaddr,0,sizeof(myaddr));
    myaddr.sin_family = AF_INET ;
    myaddr.sin_port   = htons(atoi(argv[2]));
    myaddr.sin_addr.s_addr   = inet_addr(argv[1]); 
    ret = bind(sockfd,(struct sockaddr *)&myaddr,sizeof(myaddr)) ; // 给socket 一个固定的ip 和端口 
    if(ret < 0)
    {
        perror("bind");
        exit(-1);
    }
    ret = listen(sockfd,10);
    if(ret < 0)
    {
        perror("listen");
        exit(-1);
    }
    if(sqlite3_open("my.db",&db) != SQLITE_OK)
    {
        printf("%s\n",sqlite3_errmsg(db));
        exit(-1);
    }

    while(1)
    {
        newsockfd = accept(sockfd,(struct sockaddr *)&client,&addrlen) ; 
        if(newsockfd < 0)
        {
            printf("accept");
            exit(-1);
        }
        printf("newsockfd = %d\n",newsockfd);
        printf("%s and %d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
        if( fork() == 0)
        {
            while(1)
            {
                ret = read(newsockfd,&msg,sizeof(msg_t));
                if(ret  < 0)
                {
                    printf("read");
                    exit(-1);
                }
                else if(ret == 0)
                {
                   break ; 
                }
                printf("msg.type=%c\n",msg.types);
                switch(msg.types)
                {
                    case 'R':
                        process_register(newsockfd,&msg,db);
                        break ; 
                    case 'L':
                        process_login(newsockfd,&msg,db);
                        break ; 
                    case 'Q':
                        process_query(newsockfd,&msg,db);
                        break ; 
                    case 'H':
                        process_history(newsockfd,&msg,db);
                        break ; 
                    default:
                        break ;
                }

            }
            close(newsockfd);
            exit(0);
        }

        close(newsockfd);
    }


    
    return 0;
}


client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define  N   256 
typedef struct _msg
{
    char types;
    char name[N] ;
    char text[N] ;
}msg_t;


int process_register(int sockfd,msg_t *msgp)
{
    int ret;
    msgp->types = 'R';
    printf("input your name:");
    fgets(msgp->name,N,stdin);
    msgp->name[strlen(msgp->name) -1 ] = 0 ;
    printf("input your passwd:");
    fgets(msgp->text,N,stdin);
    msgp->text[strlen(msgp->text) -1 ] = 0 ;
    ret = write(sockfd,msgp,sizeof(msg_t));
    if(ret < 0)
    {
        perror("write"); 
        exit(-1);
    }
    memset(msgp,0,sizeof(msg_t)) ;
    ret = read(sockfd,msgp,sizeof(msg_t));
    if(ret < 0)
    {
        perror("write"); 
        exit(-1);
    }
    printf("%s\n",msgp->text);

    return 0;
}
int process_query(int sockfd,msg_t *msgp)
{
    int ret;
    msgp->types = 'Q';
    while(1)
    {
        printf("input your word:");
        fgets(msgp->text,N,stdin);
        msgp->text[strlen(msgp->text) -1 ] = 0 ;
        if(strncmp(msgp->text,"#",1) == 0 ) break ;
        ret = write(sockfd,msgp,sizeof(msg_t));
        if(ret < 0)
        {
            perror("write"); 
            exit(-1);
        }
        memset(msgp,0,sizeof(msg_t)) ;
        ret = read(sockfd,msgp,sizeof(msg_t));
        if(ret < 0)
        {
            perror("write"); 
            exit(-1);
        }
        printf("%s\n",msgp->text);

    }
    return 0;
}
int process_history(int sockfd,msg_t *msgp)
{
    int ret;
    msgp->types = 'H';
    ret = write(sockfd,msgp,sizeof(msg_t));
    if(ret < 0)
    {
        perror("write"); 
        exit(-1);
    }
    memset(msgp,0,sizeof(msg_t)) ;
    while(1) 
    {
        ret = read(sockfd,msgp,sizeof(msg_t));
        if(ret < 0)
        {
            perror("write"); 
            exit(-1);
        }
        if(strncmp(msgp->text,"传输完成",sizeof("传输完成")) == 0)  break ; 
        printf("%s\n",msgp->text);
        
    }
    return 0;
}
int process_login(int sockfd,msg_t *msgp)
{
    int ret,num;
    msgp->types = 'L';
    printf("input your name:");
    fgets(msgp->name,N,stdin);
    msgp->name[strlen(msgp->name) -1 ] = 0 ;
    printf("input your passwd:");
    fgets(msgp->text,N,stdin);
    msgp->text[strlen(msgp->text) -1 ] = 0 ;
    ret = write(sockfd,msgp,sizeof(msg_t));
    if(ret < 0)
    {
        perror("write"); 
        exit(-1);
    }
    memset(msgp,0,sizeof(msg_t)) ;
    ret = read(sockfd,msgp,sizeof(msg_t));
    if(ret < 0)
    {
        perror("write"); 
        exit(-1);
    }
    printf("%s\n",msgp->text);
    if(strncmp(msgp->text,"登录成功",sizeof("登陆成功")) == 0 )
    {
        while(1)
        {
            printf("*************************************************\n");
            printf("*1:search word   2: history   3: quit************\n");
            printf("*************************************************\n");
            printf("please input your choice >:");
            scanf("%d",&num);
            scanf("%*[^\n]");scanf("%*c"); //回收残留在标准输入的字符 
            switch(num)
            {
            case 1:
                process_query(sockfd,msgp); 
                break ; 
            case 2:
                process_history(sockfd,msgp); 
                break ; 
            case 3:
                close(sockfd); 
                exit(0);
            default:
                break ;
            }

        }
        

    }

    return 0;
}

// ./a.out 192.168.1.57 8000
int main(int argc, const char *argv[])
{
    char buf[N] = {0};
    int sockfd,ret,newsockfd;
    int num;
    struct sockaddr_in server,client;
    msg_t msg;
    if(argc != 3)
    {
        printf("运行程序时带入ip 和 port\n");
        exit(-1);
    }
    socklen_t addrlen = sizeof(client);
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        perror("socket");
        exit(-1);
    }
    printf("sockfd=%d\n",sockfd);
    memset(&msg,0,sizeof(msg));
    memset(&server,0,sizeof(server));
    server.sin_family = AF_INET ;
    server.sin_port   = htons( atoi(argv[2]) );
    server.sin_addr.s_addr   = inet_addr(argv[1]); 
    ret = connect(sockfd,(struct sockaddr *)&server,sizeof(server)) ;
    if(ret < 0)
    {
        perror("connect");
        exit(-1);
    }

    while(1)
    {
        printf("*************************************************\n");
        printf("*1:register   2: login    3: quit****************\n");
        printf("*************************************************\n");
        printf("please input your choice >:");
        scanf("%d",&num);
        scanf("%*[^\n]");scanf("%*c"); //回收残留在标准输入的字符 
        switch(num)
        {
            case 1:
                process_register(sockfd,&msg); 
                break ; 
            case 2:
                process_login(sockfd,&msg); 
                break ; 
            case 3:
                close(sockfd); 
                exit(0);
            default:
                break ;
        }
        
        
    }




    printf(">:");
    fgets(buf,N,stdin);
    ret  = write(sockfd,buf,N) ;
    if(ret < 0)
    {
        perror("write");
        exit(-1);
    }
    ret = read(sockfd,buf,N);
    if(ret  < 0)
    {
        printf("read");
        exit(-1);
    }
    printf("%s\n",buf);
    close(sockfd);


    
    return 0;
}

运行时gcc server.c -o server -lsqlite3
./server 本机ip 端口号
gcc client.c -o client -lsqlite3
./client 本机ip 端口号
此外还需要个词典的文件 。自行解决。

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值