网络电子词典

C语言实现的简单网络字典服务
该代码实现了一个基于C语言的网络字典服务,包括服务器端和服务端的功能。服务器端处理客户端的连接,支持用户注册、登录、查询单词和查看历史记录。客户端则提供用户交互界面,向服务器发送请求并接收响应。服务端使用SQLite数据库存储用户信息和查询历史。

服务端

server.h

#ifndef SERVER_H_
#define SERVER_H_

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<sqlite3.h>
#include<unistd.h>
#include <signal.h>
#include<time.h>

#define L 1
#define R 2
#define Q 3
#define H 4

#define DATABASE "dictol.db"

typedef struct{
    int type;
    char name[10];
    char data[256];
}MSG;

int Create_Server(const char *ip,unsigned short port);
int MainLoop_Server(int fd_server,sqlite3 *pdb);
int Handle_Client(int fd_accept,sqlite3 *pdb);
int Handle_Register(int fd_accept,MSG *msg,sqlite3 *pdb);
int Handle_Login(int fd_accept,MSG *msg,sqlite3 *pdb);
int Handle_QueryWord(int fd_accept,MSG *msg,sqlite3 *pdb);
int Handle_History(int fd_accept,MSG *msg,sqlite3 *pdb);
int Do_SearchWord(int fd_accept,MSG *msg,char word[]);
int GetDate(char *date);
int CallBack_History(void *para,int columnCount,char **columnValue,char **columnName);

#endif 

smain.c

#include"server.h"

int main(int argc,char *argv[])
{
    sqlite3 *pdb;
    MSG msg;

    if(argc!=3)
    {
        printf("Input information is error\n");
        exit(-1);
    }

    int port;
    sscanf(argv[2],"%d",&port);
    if(port<0||port>0xffff)
    {
        printf("error port\n");
        exit(-1);
    }

    if(sqlite3_open(DATABASE,&pdb)!=SQLITE_OK)
    {
        perror("sqlite3_open");
        exit(-1);
    }

    int fd_server=Create_Server(argv[1],(unsigned short)port);

    MainLoop_Server(fd_server,pdb);
    //Viewer(fd_client,&msg);

    return 0;
}

int Create_Server(const char *ip,unsigned short port)
{
    int fd_server=socket(AF_INET,SOCK_STREAM,0);
    if(fd_server<0)
    {
        perror("socket");
        exit(-1);
    }

    struct sockaddr_in sock_struct;
    sock_struct.sin_family=AF_INET;
    sock_struct.sin_port=htons(port);
    if(inet_aton(ip,&(sock_struct.sin_addr))==0)
    {
        perror("inet_aton");
        exit(-1);
    }

    if(bind(fd_server,(struct sockaddr*)&sock_struct,sizeof(sock_struct))<0)
    {
        perror("bind");
        exit(-1);
    }

    if(listen(fd_server,8)<0)
    {
        perror("listen");
        exit(-1);
    }

    return fd_server;
}

int MainLoop_Server(int fd_server,sqlite3 *pdb)
{
    while(1)
    {
        int fd_accept=accept(fd_server,NULL,NULL);
        if(fd_accept<0)
        {
            perror("accept");
            exit(-1);
        }

        signal(SIGCHLD,SIG_IGN);

        pid_t pid;
        pid=fork();
        if(pid==0)
        {
            close(fd_server);
            Handle_Client(fd_accept,pdb);
        }
        else if(pid>0)
        {
            close(fd_accept);
        }
        else
        {
            perror("fork");
            exit(-1);
        }
    }

}

handleclient.c

#include"server.h"

int Handle_Client(int fd_accept,sqlite3 *pdb)
{
    MSG msg;
    while(recv(fd_accept,&msg,sizeof(msg),0)>0)
    {
        printf("type:%d\n",msg.type);
        switch (msg.type)
        {
        case R:
            Handle_Register(fd_accept,&msg,pdb);
            break;
        case L:
            Handle_Login(fd_accept,&msg,pdb);
            break;
        case Q:
            Handle_QueryWord(fd_accept,&msg,pdb);
            break;
        case H:
            Handle_History(fd_accept,&msg,pdb);
            break;
        default:
            break;
        }
    }
    printf("client exit\n");
    close(fd_accept);
    exit(0);
}

int Handle_Register(int fd_accept,MSG *msg,sqlite3 *pdb)
{
    char *errmsg;
    char sql[512];
    sprintf(sql,"INSERT INTO user VALUES('%s','%s');",msg->name,msg->data);
    if(sqlite3_exec(pdb,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
    {
        printf("%s\n",errmsg);
        strcpy(msg->data,"user name is already exist\n");
    }
    else
    {
        printf("Insert success\n");
        strcpy(msg->data,"OK");
    }
    if(send(fd_accept,msg,sizeof(MSG),0)<0)
    {
        perror("send");
        return -1;
    }
    return 0;
}

int Handle_Login(int fd_accept,MSG *msg,sqlite3 *pdb)
{
    char sql[512];
    char *errmsg;
    int nrow;
    int ncolumn;
    char **resultp;

    sprintf(sql,"SELECT * FROM user WHERE name='%s' AND password ='%s';",msg->name,msg->data);
    printf("%s\n",sql);

    if(sqlite3_get_table(pdb,sql,&resultp,&nrow,&ncolumn,&errmsg)!=SQLITE_OK)
    {
        printf("%s\n",errmsg);
        return -1;
    }

    if(nrow==1)
    {
        strcpy(msg->data,"OK");
        send(fd_accept,msg,sizeof(MSG),0);
        return 1;
    }
    else//if(nrow==0)
    {
        strcpy(msg->data,"name/password is wrong\n");
        send(fd_accept,msg,sizeof(MSG),0);
    }
    return 0;
}

int Handle_QueryWord(int fd_accept,MSG *msg,sqlite3 *pdb)
{
    char word[64];
    int found=0;
    char date[128];
    char sql[256];
    char *errmsg;

    strcpy(word,msg->data);

    found=Do_SearchWord(fd_accept,msg,word);

    if(found==1)
    {
        GetDate(date);
        printf("%s\n",date);


        sprintf(sql,"INSERT INTO record VALUES('%s','%s','%s');",msg->name,date,word);
        printf("%s\n",sql);

        if(sqlite3_exec(pdb,sql,NULL,NULL,&errmsg)!=SQLITE_OK)
        {
            printf("%s\n",errmsg);
            return -1;
        }
        else
        {
            printf("Insert record done\n");
        }
    }
    else
    {
        strcpy(msg->data,"Not Found");
    }
    printf("%s\n",msg->data);
    send(fd_accept,msg,sizeof(MSG),0);

    return 0;
}

int Handle_History(int fd_accept,MSG *msg,sqlite3 *pdb)
{
    char sql[128];
    char *errmsg;

    sprintf(sql,"SELECT * FROM record WHERE name='%s';",msg->name);

    if(sqlite3_exec(pdb,sql,CallBack_History,(void*)&fd_accept,&errmsg)!=SQLITE_OK)
    {
        printf("%s\n",errmsg);
    }
    else
    {
        printf("Query record done\n");
    }

    msg->data[0]='\0';
    send(fd_accept,msg,sizeof(MSG),0);

    return 0;
}

int CallBack_History(void *para,int columnCount,char **columnValue,char **columnName)
{
    int fd_accpet;
    MSG msg;
    fd_accpet=*((int*)para);
    sprintf(msg.data,"%s,%s",columnValue[1],columnValue[2]);
    send(fd_accpet,&msg,sizeof(MSG),0);

    return 0;
}

int Do_SearchWord(int fd_accept,MSG *msg,char word[])
{
    FILE *fp;
    int len=strlen(word);
    char buf[512];
    int result;
    char *p;

    if((fp=fopen("dict.txt","r"))==NULL)
    {
        perror("fopen");
        strcpy(msg->data,"Failed to open dict.txt");
        send(fd_accept,msg,sizeof(MSG),0);
        return -1;
    }

    
    printf("%s,len=%d\n",word,len);

    while(fgets(buf,512,fp)!=NULL)
    {
        result=strncmp(buf,word,len);
        if(result!=0)
        {
            continue;
        }
        if(buf[len]!=' ')
        {
            break;
        }

        p=buf+len;
        while(*p==' ')
        {
            p++;
        }
        strcpy(msg->data,p);
        printf("found word:%s\n",msg->data);

        fclose(fp);
        return 1;
    }
    fclose(fp);
    return 0;
}

int GetDate(char *date)
{
    time_t t;
    struct tm *tp;

    time(&t);
    tp=localtime(&t);

    sprintf(date,"%d-%d-%d %d:%d:%d",tp->tm_year+1900,tp->tm_mon+1,tp->tm_mday,tp->tm_hour,tp->tm_min,tp->tm_sec);
    printf("get date:%s\n",date);
    return 0;
}

客户端

client.h

#ifndef CLIENT_H_
#define CLIENT_H_

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<sqlite3.h>
#include<unistd.h>
#include <signal.h>
#include<time.h>

#define L 1
#define R 2
#define Q 3
#define H 4

typedef struct{
    int type;
    char name[10];
    char data[256];
}MSG;

int Create_Client(const char *ip,unsigned short port);
int Viewer(int fd_client,MSG *msg);
int Do_UserRegister(int fd_client,MSG *msg);
int Do_UserLogin(int fd_client,MSG *msg);
int Do_UserQuery(int fd_client,MSG *msg);
int Do_UserHistory(int fd_client,MSG *msg);

#endif 

cmain.c

#include"client.h"

int main(int argc,char *argv[])
{
    if(argc!=3)
    {
        printf("Input information is error\n");
        exit(-1);
    }

    int port;
    sscanf(argv[2],"%d",&port);
    if(port<0||port>0xffff)
    {
        printf("error port\n");
        exit(-1);
    }
    int fd_client=Create_Client(argv[1],(unsigned short)port);

    MSG msg;
    Viewer(fd_client,&msg);

    return 0;
}

int Create_Client(const char *ip,unsigned short port)
{
    int fd_client=socket(AF_INET,SOCK_STREAM,0);
    if(fd_client<0)
    {
        perror("socket");
        exit(-1);
    }

    struct sockaddr_in sock_struct;
    sock_struct.sin_family=AF_INET;
    sock_struct.sin_port=htons(port);
    if(inet_aton(ip,&(sock_struct.sin_addr))==0)
    {
        perror("inet_aton");
        exit(-1);
    }

    if(connect(fd_client,(struct sockaddr*)&sock_struct,sizeof(sock_struct))<0)
    {
        perror("connect");
        exit(-1);
    }

    return fd_client;
}

history.c

#include"client.h"

int Do_UserHistory(int fd_client,MSG *msg)
{
    msg->type=H;
    send(fd_client,msg,sizeof(MSG),0);
    while(1)
    {
        recv(fd_client,msg,sizeof(MSG),0);
        if(msg->data[0]=='\0')
            break;
        printf("%s\n",msg->data);
    }

    return 1;
}

login.c

#include"client.h"

int Do_UserLogin(int fd_client,MSG *msg)
{
    msg->type=L;
    printf("Please input name:\n");
    scanf("%s",msg->name);
    getchar();

    printf("Please input password:\n");
    scanf("%s",msg->data);

    if(send(fd_client,msg,sizeof(MSG),0)<0)
    {
        perror("send");
        return -1;
    }

    if(recv(fd_client,msg,sizeof(MSG),0)<0)
    {
        perror("recv");
        return -1;
    }

    if(strncmp(msg->data,"OK",2)==0)
    {
        printf("Login success\n");
        return 1;
    }
    else
    {
        printf("%s\n",msg->data);
    }
    return 0;
}

query.c

#include"client.h"

int Do_UserQuery(int fd_client,MSG *msg)
{
    msg->type=Q;
    puts("********************");

    while(1)
    {
        printf("Please input word:\n");
        scanf("%s",msg->data);
        getchar();
        if(strncmp(msg->data,"#",1)==0)
        {
            break;
        }

        if(send(fd_client,msg,sizeof(MSG),0)<0)
        {
            perror("send");
            return -1;
        }

        if(recv(fd_client,msg,sizeof(MSG),0)<0)
        {
            perror("recv");
            return -1;
        }
        printf("%s\n",msg->data);
    }

    return 0;
}

register.c

#include"client.h"

int Do_UserRegister(int fd_client,MSG *msg)
{
    msg->type=R;
    printf("Please input name:\n");
    scanf("%s",msg->name);
    getchar();

    printf("Please input password:\n");
    scanf("%s",msg->data);

    if(send(fd_client,msg,sizeof(MSG),0)<0)
    {
        perror("send");
        return -1;
    }

    if(recv(fd_client,msg,sizeof(MSG),0)<0)
    {
        perror("recv");
        return -1;
    }

    printf("%s",msg->data);

    return 0;
}

viewer.c

#include"client.h"

int Viewer(int fd_client,MSG *msg)
{
    int flag;
    while(1)
    {
        printf("************************************\n");
        printf("Welcome to the Electronic Dictionary\n");
        printf("****1.Login  2.Register  0.EXIT****\n");
        printf("************************************\n");
        scanf("%d",&flag);
        getchar();

        switch(flag)
        {
            case 1:
                if(Do_UserLogin(fd_client,msg)==1)
                {
                    goto next;
                }
                break;
            case 2:
                Do_UserRegister(fd_client,msg);
                break;
            case 0:
                close(fd_client);
                exit(0);
                break;
            default:
                break;
        }
    }
next:
    while(1)
    {
        printf("**********************************************\n");
        printf("*****Welcome to the Electronic Dictionary*****\n");
        printf("****1.query word  2.history record  0.EXIT****\n");
        printf("**********************************************\n");
        scanf("%d",&flag);
        getchar();

        switch(flag)
        {
            case 1:
                Do_UserQuery(fd_client,msg);
                break;
            case 2:
                Do_UserHistory(fd_client,msg);
                break;
            case 0:
                close(fd_client);
                exit(0);
                break;
            default:
                break;
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值