电子词典项目

服务器(server):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sqlite3.h>
#include <signal.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>

#define N 16
#define R 1 // user register 用户注册
#define L 2 // user login 用户登录
#define Q 3 // query word 查询词
#define H 4 // history record 历史记录

#define DATABASE “my.db”
typedef struct
{
int type; //选择操作
char name[N]; //名字
char data[256]; // password or word
} MSG;

//----------------------建立函数-----------------------------------------------
//注册表
void do_register(int acceptfd, MSG *msg, sqlite3 *db);
//登录
void do_login(int acceptfd, MSG *msg, sqlite3 *db);
//查询
void do_query(int acceptfd, MSG *msg, sqlite3 *db);
//历史
void do_history(int acceptfd, MSG *msg, sqlite3 *db);
//客户端
void do_client(int acceptfd, sqlite3 *db);
//搜索字
int do_searchword(int acceptfd, MSG *msg);
void getdata(char *date);
int history_callback(void *arg, int f_num, char **f_value, char **f_name);

//------------------------------------------------------------------------

int main(int argc, const char *argv[])
{
//句柄指建立一个数据库指针用来保存数据库的所在,通过句柄可以读取调用数据库
sqlite3 *db;
//创建进程
pid_t pid = 0;
//建立连接接收值
int acceptfd = 0;

//健壮性判断
if (3 != argc)
{
    printf("usage: %s <ip> <port>", argv[0]);
    exit(-1);
}
//打开数据库
if (sqlite3_open(DATABASE, &db) != SQLITE_OK)
{
    // sqlite3_errmsg(db)为获取错误信息函数
    printf("sqlite3 error: %s\n", sqlite3_errmsg(db));
    exit(-1);
}
//套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == sockfd)
{
    perror("socket error");
    exit(-1);
}
//填充网络信息结构体
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
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);
//套接字绑定
if (-1 == bind(sockfd, (struct sockaddr *)&serveraddr, serveraddr_len))
{
    perror("bind error");
    exit(-1);
}
//监听
if (-1 == listen(sockfd, 5))
{
    perror("listen error");
    exit(-1);
}

while (1)
{
    //接受客户端发来的信号
    if (-1 == (acceptfd = accept(sockfd, NULL, NULL)))
    {
        perror("accept error");
        exit(-1);
    }
    //创建父子进程
    pid = fork();
    if (-1 == pid)
    { //进程错误
        perror("fork error");
        exit(-1);
    }
    else if (0 == pid)
    { //子进程
        //客户端数据接受处理
        do_client(acceptfd, db);
    }
    else if (0 < pid)
    { //父进程
        close(acceptfd);
    }
}

return 0;

}

//客户端
void do_client(int acceptfd, sqlite3 *db)
{
//建立结构体类型
MSG msg;
//读取客户端发来的信息选择请求
while (0 < recv(acceptfd, &msg, sizeof(MSG), 0))
{
// printf(“type = %d\n”, msg.type);
// printf(“type = %s\n”, msg.data);
switch (msg.type)
{
case R:
do_register(acceptfd, &msg, db);
break;
case L:
do_login(acceptfd, &msg, db);
break;
case Q:
do_query(acceptfd, &msg, db);
break;
case H:
do_history(acceptfd, &msg, db);
break;
}
}
printf(“client quit\n”);
exit(0);
return;
}
//登录
//所谓登录就是检验创建是否成功在usr用户下有没有对应的用户信息密码
void do_login(int acceptfd, MSG *msg, sqlite3 *db)
{

char sqlstr[500] = {0};
char **result = NULL;
int nrow = 0;
int ncolumn = 0;
int ret = 0;
sprintf(sqlstr, "SELECT * FROM usr WHERE name = '%s' and pass = %s", msg->name, msg->data);
printf("yfs : [%s]\n", sqlstr);
if (SQLITE_OK != (ret = sqlite3_get_table(db, sqlstr, &result, &nrow, &ncolumn, NULL)))
{
    printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
           __FILE__, __LINE__, ret, sqlite3_errmsg(db));
    exit(-1);
}
//查询结果便利打印
int i = 0;
int j = 0;
int index;

//查找对应的
for (i = 0; i < ncolumn; i++)
{
    printf("%-10s", result[i]);
}
printf("\n");
index = i;
for (i = 0; i < nrow; i++)
{
    for (j = 0; j < ncolumn; j++)
    {
        printf("%-10s", result[index++]);
        strncpy(msg->data, "OK", 256);
    }
    printf("\n");
}
send(acceptfd, msg, sizeof(MSG), 0);
//释放内存
sqlite3_free_table(result);
return ;

}
//注册表
void do_register(int acceptfd, MSG *msg, sqlite3 *db)
{
int ret = 0;
//组装sql语句
char sqlstr[500] = {0};
char return_info[500];
sprintf(sqlstr, “INSERT INTO usr values(‘%s’,‘%s’)”, msg->name, msg->data);
//执行sql语句
printf(“yfs : [%s]\n”, sqlstr);
if (SQLITE_OK != (ret = sqlite3_exec(db, sqlstr, NULL, NULL, NULL)))
{
printf(“文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n”, FILE, LINE, ret, sqlite3_errmsg(db));
exit(-1);
}
else
{
sprintf(return_info, “INSERT INTO usr value(‘%s’,‘%s’) is OK”, msg->name, msg->data);
strcpy(msg->data, return_info);
}
send(acceptfd, msg, sizeof(MSG), 0);
printf(“用户注册成功…\n”);
}

//查询
void do_query(int acceptfd, MSG *msg, sqlite3 *db)
{
char sqlstr[500];
char word[500];
int found = 0;
char date[500];
int ret = 0;
char *errmsg;
//保存到word中
strcpy(word, msg->data);
//在文件中查询单词
found = do_searchword(acceptfd, msg);
// found 找到单词接到函数返回值为 1 未找到返回值 0
//如果执行成功,还需要保存历史记录
if (found == 1)
{
//获取时间
getdata(date);
//通过sqlite3_exec函数插入数据
sprintf(sqlstr, “INSERT INTO record values(‘%s’,‘%s’,‘%s’)”, msg->name, date, word);
//执行sql语句
// printf(“yfs : [%s]\n”, sqlstr);
if (SQLITE_OK != (ret = sqlite3_exec(db, sqlstr, NULL, NULL, &errmsg)))
{
printf(“文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n”, FILE, LINE, ret, sqlite3_errmsg(db));
exit(-1);
}
}
send(acceptfd, msg, sizeof(MSG), 0);
return;
}

//搜索字
int do_searchword(int acceptfd, MSG *msg)
{
char temp[300];
int len, result;
char *p;
len = strlen(msg->data);
//打开dict.txt文件
FILE *fp;
if (NULL == (fp = fopen(“dict.txt”, “r”)))
{
strcpy(msg->data, “dict.txt can not open”);
send(acceptfd, msg, sizeof(MSG), 0);
}
//读取并且比较
while (fgets(temp, 300, fp) != NULL)
{
//设置时间
result = strncmp(msg->data, temp, len);
//比较单词
if (result == 0 && temp[len] == ’ ')
{
//读取的单词的地址首位+单词长度 = p
p = temp + len;
while (*p == ’ ')
{
p++;
}
strcpy(msg->data, p);
fclose(fp);
//找到就直接退出
return 1;
}
}
//未找到
strcpy(msg->data, “not found”);
fclose(fp);
return 0;
}
//设置时间
void getdata(char *date)
{
time_t t;
struct tm *tp;
time(&t);
tp = localtime(&t);
sprintf(date, “%d-%d-%d %d:%d:%d”, 1900 + tp->tm_year, 1 + tp->tm_mon, tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec);
}

//历史
void do_history(int acceptfd, MSG *msg, sqlite3 *db)
{
int ret = 0;
//组装sql语句
char sqlstr[500] = {0};
char *errmsg;
sprintf(sqlstr, “SELECT * FROM record WHERE name = ‘%s’”, msg->name);
//执行sql语句
// printf(“yfs : [%s]\n”, sqlstr);
if (SQLITE_OK != (ret = sqlite3_exec(db, sqlstr, history_callback, (void *)&acceptfd, &errmsg)))
{
printf(“文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n”, FILE, LINE, ret, sqlite3_errmsg(db));
exit(-1);
}
}
//通过回调函数发送时间和单词
int history_callback(void *arg, int f_num, char **f_value, char **f_name)
{
int acceptfd;
MSG msg;
acceptfd = *(int *)arg;
sprintf(msg.data, “%s : %s”, f_value[1], f_value[2]);
send(acceptfd, &msg, sizeof(MSG), 0);
return 0;
}

客户机(client):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sqlite3.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define N 16
#define R 1 // user register
#define L 2 // user login
#define Q 3 // query word
#define H 4 // history record

#define DATABASE “my.db”

typedef struct
{
int type;
char name[N];
char data[500]; // password or word or remark
} MSG;

//-----------------------构建函数---------------------------------------
//注册
void do_register(int socketfd, MSG *msg);
//登录
int do_login(int socketfd, MSG *msg);
//查询
void do_query(int socketfd, MSG *msg);
//历史
void do_history(int socketfd, MSG *msg);

//----------------------------------------------------------------

int main(int argc,const char * argv[]){
//定义结构体类型
MSG msg;

//健壮性判断
if(3 != argc){
    printf("usage: %s <ip> <port>",argv[0]);
    exit(-1);
}
//套接字
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(-1 == sockfd){
    perror("socket error");
    exit(-1);
}
//填充网络信息结构体
struct sockaddr_in serveraddr;
memset(&serveraddr,0,sizeof(serveraddr));
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);

//与服务器建立连接
if(-1 == connect(sockfd,(struct sockaddr*)&serveraddr,serveraddr_len)){
    perror("connect error");
    exit(-1);
}

//功能选择向服务器输出值
int choose = 0;
while(1){
  	printf("************************************\n");
	printf("* 1: register   2: login   3: quit *\n");
	printf("************************************\n");
	printf("please choose : ");  

    if(!scanf("%d",&choose)){
        perror("scanf1 error");
        exit(-1);
    }

    switch(choose){
        case 1:
            do_register(sockfd,&msg);
            break;
        case 2:
            if(1 == do_login(sockfd,&msg)){
                goto NEXT;
            }
            break;
        case 3:
            close(sockfd);
            exit(0);
    }
}

NEXT:
//功能选择

while(1){
    printf("************************************\n");
	printf("* 1: query   2: history   3: quit  *\n");
	printf("************************************\n");
	printf("please choose : ");

    if(!scanf("%d",&choose)){
        perror("scanf2 error");
        exit(-1);
    }

    switch(choose){
        case 1:
            do_query(sockfd,&msg);
            break;
        case 2:
            do_history(sockfd,&msg);
            break;
        case 3:
            close(sockfd);
            exit(0);//成功退出
            break;

    }
}
return 0;

}

//注册
void do_register(int sockfd, MSG *msg){
//指定操作码
msg->type = R;
//输入用户名
printf(“input your name:>”);
scanf(“%s”,msg->name);
//输入密码
printf(“input your password:>”);
scanf(“%s”,msg->data);
//发送数据
send(sockfd,msg,sizeof(MSG),0);
//接收数据并输出
recv(sockfd,msg,sizeof(MSG),0);
//程序执行结果输出确认
printf(“register: name=[%s]—password=[%s]\n”,msg->name,msg->data);

return;

}
//登录
int do_login(int socketfd, MSG *msg) {
//设置操作码
msg->type = L;
//输入用户名
printf(“input your name:>”);
scanf(“%s”,msg->name);
//输入密码
printf(“input your password:>”);
scanf(“%s”,msg->data);
//发送数据给服务器
send(socketfd, msg, sizeof(MSG), 0);
//接收服务器发送的数据
recv(socketfd, msg, sizeof(MSG), 0);
//判断是否登录成功
if(strncmp(msg->data, “OK”, 3) == 0){ //用3 可以防止 OK 和 OKkshdfkj
//登录成功返回1
printf(“login : OK\n”);
return 1;
}
//登录失败返回0
printf(“login error : %s\n”, msg->name);
return 0;
}

//查询
void do_query(int socketfd, MSG *msg){
//设置操作码
msg->type = Q;
while(1){
puts(“-----------------------------------------”);
puts(“---------查询输入要查询的内容-------------”);
puts(“----------输入#退出返回上一级-------------”);
printf(“input word :>”);
scanf(“%s”,msg->data);

    if( 0 == strcmp(msg->data,"#") ){
        break;
    }
    send(socketfd,msg,sizeof(MSG),0);
    recv(socketfd,msg,sizeof(MSG),0);
    printf("正在查询>>> %s\n",msg->data);
}
return;

}
//历史
void do_history(int socketfd, MSG *msg){
msg->type = H;
send(socketfd,msg,sizeof(MSG),0);
//确认返回结果
while(1){
recv(socketfd,msg,sizeof(MSG),0);
if(strcmp(msg->data,“OVER”) == 0){
break;
}
printf(“%s\n”,msg->data);
}
return;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值