代码中的ip地址写的都是回环测试ip,如果要在两个电脑之间,请修改代码中ip地址一行。另外查询单词的dict.txt文件您需要自己准备,然后修改路径。
写的不好,您多担待。
服务器部分:
头文件声明(服务器)
#ifndef _SERVER_H
#define _SERVER_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define N 256
#define M 1024//用于缓冲区
typedef struct msgg{
unsigned int cmd;//标志请求
char name[N];//用户名
char password[N];//密码
}msg;
typedef struct worr{
unsigned int cmd;//标志请求
char word[N];//所要查询的单词
char time[N];//查询时间
char explain[N];
char name[N];
}data;
typedef struct sockaddr *SA;
int enroll(msg *pack);
int enter(msg *pack);
int history(data *word);
int init_network();
int look(data *word);
int sec(msg *pack);
int sec1(data *word);
#endif
主函数(服务器)
#include "server.h"
int main(int argc, char *argv[])
{
int lis_fd;
int soc_fd;
int ret;
struct sockaddr_in cliaddr;
msg pack;
data word;
socklen_t addrlen = 0;
char buf[M] = "\0";
lis_fd = init_network();
if (-1 == lis_fd)
{
printf("init network fail\n");
return -1;
}
else
{
printf("init succeed, have fun ^0^\n");
}
bzero(&pack, sizeof(pack));
while (1)
{
printf("等待接收...\n");
soc_fd = accept(lis_fd, (SA)&cliaddr, &addrlen);
if (-1 == soc_fd)
{
perror("accept");
return -1;
}
while (1)
{
if (recv(soc_fd, buf, M, 0) > 0)
{
printf("接收信息成功\n");
memcpy(&pack, buf, sizeof(pack));
printf("%s %s\n",pack.name, pack.password);
ret = sec(&pack);
if (1 == ret)
{
bzero(buf, sizeof(buf));
strcpy(buf, "ok");
send(soc_fd, buf, M, 0);
printf("注册成功信息已发出\n");
break;
}
else if (-1 == ret)
{
bzero(buf, sizeof(buf));
strcpy(buf, "no");
send(soc_fd, buf, M, 0);
printf("注册失败信息已发出\n");
break;
}
else if (2 == ret)
{
bzero(buf, sizeof(buf));
strcpy(buf, "ok");
send(soc_fd, buf, M, 0);
printf("登陆成功信息已发出\n");
bzero(buf, sizeof(buf));
while(recv(soc_fd, buf, M, 0) > 0)
{
printf("接收数据包成功\n");
memcpy(&word, buf, sizeof(word));
if (0 == strncmp(word.word, "#", 1))
break;
ret = sec1(&word);
if (1 == ret)
{
printf("查到了此单词\n");
bzero(buf, sizeof(buf));
strcpy(buf, "ok");
send(soc_fd, buf, M, 0);
printf("查询成功信息已发出\n");
bzero(buf, sizeof(buf));
memcpy(buf, &word, sizeof(word));
send(soc_fd, buf, M, 0);
}
else if (-1 == ret)
{
printf("查不到此单词\n");
bzero(buf, sizeof(buf));
strcpy(buf, "no");
send(soc_fd, buf, M, 0);
printf("查询失败信息已发出\n");
}
else if (2 == ret)
{
sqlite3 *db;
int ret;
char **result;
int row, column;
char *errmsg;
char sql[M] = "\0";
char buf[M] = "\0";
int set[2] = {0};
ret = sqlite3_open("my.db", &db);
if (ret != SQLITE_OK)
{
printf("数据库打开失败\n");
return -1;
}
else
{
printf("数据库打开成功\n");
}
sprintf(sql, "select * from %s;",pack.name);
ret = sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);
if (ret != SQLITE_OK)
{
printf("数据库语句执行失败\n");
sqlite3_free_table(result);
sqlite3_close(db);
break;
}
else
{
int i, j, k=0;
printf("数据库语句执行成功\n");
for (i=0; ifor (j=0; j<=column; j++)
{
send(soc_fd, result[k++], N , 0);
}
}
sqlite3_free_table(result);
sqlite3_close(db);
break;
}
}
}
break;
}
else if (-2 == ret)
{
bzero(buf, sizeof(buf));
strcpy(buf, "no");
send(soc_fd, buf, M, 0);
printf("登陆失败信息已发出\n");
continue;
}
}
else
{
printf("接收失败或者用户已下线\n");
break;
}
}
close(soc_fd);
}
}
功能函数(服务器)
#include "server.h"
unsigned short port = 8888;
int init_network()
{
int lis_fd;
int ret;
struct sockaddr_in seraddr;
lis_fd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == lis_fd)
{
perror("socket");
return -1;
}
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(port);
seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(lis_fd, (SA)&seraddr, sizeof(seraddr));
if (-1 == ret)
{
perror("bind");
return -1;
}
listen(lis_fd, 5);
return lis_fd;
}
int enroll(msg *pack)
{
sqlite3 *db;
int ret;
char *errmsg;
char sql[M] = "\0";
char buf[M] = "\0";
ret = sqlite3_open("my.db", &db);
if (ret != SQLITE_OK)
{
printf("数据库打开失败\n");
return -1;
}
else
{
printf("数据库打开成功\n");
}
sprintf(sql, "create table if not exists user(name text primary key, password text)");
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf("数据库语句执行失败\n");
return -1;
}
else
{
printf("数据库语句执行成功\n");
}
bzero(sql, sizeof(sql));
sprintf(sql, "insert into user values('%s','%s')", pack->name, pack->password);
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf("信息载入失败\n");
sqlite3_close(db);
return -1;
}
else
{
printf("信息载入成功\n");
printf("注册成功\n");
sqlite3_close(db);
return 1;
}
}
int enter(msg *pack)
{
sqlite3 *db;
int ret;
char **result;
int row, column;
char *errmsg;
char sql[M] = "\0";
char buf[M] = "\0";
ret = sqlite3_open("my.db", &db);
if (ret != SQLITE_OK)
{
printf("数据库打开失败\n");
return -1;
}
else
{
printf("数据库打开成功\n");
}
sprintf(sql, "select name,password from user where name='%s';", pack->name);
ret = sqlite3_get_table(db, sql, &result, &row, &column, &errmsg);
if (ret != SQLITE_OK)
{
printf("数据库语句执行失败\n");
sqlite3_free_table(result);
sqlite3_close(db);
return -2;
}
else
{
printf("数据库语句执行成功\n");
if (0 == strcmp(result[3], pack->password))
{
sqlite3_free_table(result);
sqlite3_close(db);
return 2;
}
else
return -2;
}
}
int sec(msg *pack)
{
int ret;
msg pack1;
pack1 = *pack;
switch (pack->cmd)
{
case 1:
ret = enroll(&pack1);
break;
case 2:
ret = enter(&pack1);
break;
}
return ret;
}
int history(data *word)
{
sqlite3 *db;
int ret;
char *errmsg;
char sql[M] = "\0";
char buf[M] = "\0";
ret = sqlite3_open("my.db", &db);
if (ret != SQLITE_OK)
{
printf("数据库打开失败\n");
return -1;
}
else
{
printf("数据库打开成功\n");
}
sprintf(sql, "create table if not exists %s(word text, time text)",word->name);
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf("数据库语句执行失败\n");
return -1;
}
else
{
printf("数据库语句执行成功\n");
}
bzero(sql, sizeof(sql));
sprintf(sql, "insert into %s values('%s','%s')", word->name, word->word, word->time );
ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);
if (ret != SQLITE_OK)
{
printf("历史信息载入失败\n");
sqlite3_close(db);
return -1;
}
else
{
printf("历史信息载入成功\n");
sqlite3_close(db);
return 1;
}
}
int look(data *word)
{
printf("%s\n",word->word);
word->time[strlen(word->time)-1] = '\0';
history(word);
char buf[M] = "\0";
FILE *fp;
char *buff = buf;
char word1[N] = "\0";
int i = 0;
if ((fp = fopen("dict.txt", "r")) == NULL)
{
perror("fopen");
return -1;
}
else
{
printf("查询中\n");
}
strcpy(word1, word->word);
while (word1[i] != '\0')
{
i++;
}
word1[i] = ' ';
word1[i+1] = '\0';
while (fgets(buf, M, fp) != NULL)
{
if (!strncmp(buf, word1, i))
break;
}
if (!strncmp(buf, word1, i))
{
while (*(++buff) != ' ')
{
continue;
}
while (*(++buff) == ' ')
continue;
bzero(word->explain, sizeof(word->explain));
strcpy(word->explain, buff);
fclose(fp);
return 1;
}
else
{
printf("没找到\n");
fclose(fp);
return -1;
}
}
int sec1(data *word)
{
int ret;
switch (word->cmd)
{
case 1:
ret = look(word);
break;
case 2:
ret = 2;
break;
}
return ret;
}
makefile(服务器)
.PHONY:clean
OBJ = server
OBJS = server.o fun_ser.o server.h
cc = gcc
flag = -c -o
$(OBJ):$(OBJS)
@$(cc) $^ -lsqlite3 -o $@
%.o:%.c
@$(cc) $< $(flag) $@
clean:
rm $(OBJS) $(OBJ)
客户端部分:
头文件(客户端)
```
#ifndef _CLIENT_H
#define _CLIENT_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define N 256
#define M 1024//用于缓冲区
typedef struct msgg{
unsigned int cmd;//标志请求
char name[N];//用户名
char password[N];//密码
}msg;
typedef struct worr{
unsigned int cmd;//标志请求
char word[N];//所要查询的单词
char time[N];//查询时间
char explain[N];
char name[N];
}data;
typedef struct sockaddr *SA;
msg enroll();
msg enter();
data history(msg *pack);
int init_connect();
data look();
int menu1();
int menu2();
void quit();
int sec();
#endif
主函数(客户端)
#include"client.h"
int main(int argc, char *argv[])
{
while (1)
{
int soc_fd;
int i = 0;
int ret;
char buf[M] = "\0";
msg pack;
data word;
int set[2] = {0};
soc_fd = init_connect();
if (-1 == soc_fd)
{
printf("连接失败\n");
}
else
{
printf("连接成功^0^\n");
}
menu1();
ret = sec();
switch (ret)
{
case 1:
pack = enroll();//注册;
bzero(buf, sizeof(buf));
memcpy(buf, &pack,sizeof(pack));
send(soc_fd, buf, M, 0);//将信息发送给服务器
bzero(buf, sizeof(buf));
recv(soc_fd, buf, M, 0);//从服务器那接受确认信息
if (strncmp(buf, "ok", 2) == 0)
{
printf("注册成功\n");
break;
}
else if (strncmp(buf, "no", 2) == 0)
{
printf("注册失败\n");
break;
}
case 2:
pack = enter();//登陆;
bzero(buf, sizeof(buf));
memcpy(buf, &pack,sizeof(pack));
send(soc_fd, buf, M, 0);//将信息发送给服务器
bzero(buf, sizeof(buf));
recv(soc_fd, buf, M, 0);//从服务器那接受确认信息
if (strncmp(buf, "ok", 2) == 0)
{
printf("登陆成功\n");
menu2();
ret = sec();
switch (ret)
{
case 1:
while (1)
{
word = look();
if (strncmp(word.word, "#", 1) == 0)
break;
strcpy(word.name, pack.name);
printf("%s",word.time);
bzero(buf, sizeof(buf));
memcpy(buf, &word, sizeof(word));
send(soc_fd, buf, M, 0);//将信息发送给服务器
bzero(buf, sizeof(buf));
recv(soc_fd, buf, M, 0);//从服务器那接受确认信息
if (strncmp(buf, "ok", 2) == 0)
{
bzero(buf, sizeof(buf));
recv(soc_fd, buf, M, 0);
memcpy(&word, buf, sizeof(word));
printf("%s\n",word.explain);
}
else if (strncmp(buf, "no", 2) == 0)
{
printf("找不到此单词\n");
}
}
case 2:
word = history(&pack);
bzero(buf, sizeof(buf));
memcpy(buf, &word, sizeof(word));
send(soc_fd, buf, M, 0);//将信息发送给服务器
i=0;
bzero(buf, sizeof(buf));
while (1)
{
if(recv(soc_fd, buf, N, 0) > 0)
{
printf("%-8s", buf);
i++;
if (i%2 == 0)
printf("\n");
}
else
break;
}
case 3:
continue;
}
break;
}
else if (strncmp(buf, "no", 2) == 0)
{
printf("登陆失败\n");
break;
}
case 3:
quit();
}
}
}
功能函数(客户端)
unsigned short port = 8888;
int init_connect()
{
int soc_fd;
int ret;
struct sockaddr_in seraddr;
soc_fd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == soc_fd)
{
perror("socket");
return -1;
}
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(port);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = connect(soc_fd, (SA)&seraddr, sizeof(seraddr)) ;
if (-1 == ret)
{
perror("connect");
return -1;
}
else
{
return soc_fd;
}
}
int menu2()
{
printf(“****************************\n”);
printf(“* 1.查询单词 2.历史记录 3.退出 *\n”);
printf(“****************************\n”);
}
int menu1()
{
printf(“****************************\n”);
printf(“* 1.注册 2.登陆 3.退出 *****\n”);
printf(“****************************\n”);
}
int sec()
{
int i;
printf(“请选择:\n”);
scanf(“%d”,&i);
getchar();
return i;
}
msg enroll()
{
msg pack;
char buf[N] = “\0”;
pack.cmd = 1;
printf(“注册\n”);
printf(“请输入用户名:\n”);
fgets(buf, N, stdin);
buf[strlen(buf)-1] = ‘\0’;
strcpy(pack.name, buf);
bzero(buf, N);
printf(“请输入密码:\n”);
fgets(buf, N, stdin);
buf[strlen(buf)-1] = ‘\0’;
strcpy(pack.password, buf);
return pack;
}
msg enter()//登陆
{
msg pack;
char buf[N] = “\0”;
pack.cmd = 2;
printf(“登陆\n”);
printf(“请输入用户名:\n”);
fgets(buf, N, stdin);
buf[strlen(buf)-1] = ‘\0’;
strcpy(pack.name, buf);
bzero(buf, N);
printf(“请输入密码:\n”);
fgets(buf, N, stdin);
buf[strlen(buf)-1] = ‘\0’;
strcpy(pack.password, buf);
return pack;
}
void quit()
{
printf(“再见,拜拜,欢迎下次再来-0-\n”);
exit(0);
}
data look()
{
data word;
time_t t;
char buf[N] = “\0”;
word.cmd = 1;
printf(“查询\n”);
printf(“请输入你需要查询的单词:”);
bzero(buf,N);
fgets(buf, N, stdin);
buf[strlen(buf)-1] = ‘\0’;
strcpy(word.word,buf);
t = time(NULL);
strcpy(word.time,asctime(localtime(&t)));
return word;
}
data history(msg *pack)
{
data word;
word.cmd = 2;
strcpy(word.name,pack->name);
return word;
}
makefile(客户端)
.PHONY:clean
OBJ = client
OBJS = client.o fun_cli.o client.h
cc = gcc
flag = -c -o
(OBJ): (OBJS)
@ (cc) ^ -o @@ (cc) < (flag) @clean:rm (OBJS) $(OBJ)
“`