服务器:
main.c
#include "1.h"
//发送接收结构体
int main(int argc, const char *argv[])
{
//捕获17号信号 SIGCHLD
sighandler_t s = signal(17, handler);
if(SIG_ERR == s)
{
ERR_MSG("signal");
return -1;
}
//检查是否有单词数据库,创建用户数据库
word_exist();
printf("初始化完成\n");
//TCP连接
int sfd = tcp_lianjie();
//等待客户端连接
printf("等待客户端连接\n");
int newfd = 0;
pid_t pid = 0;
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
while(1)
{
//父进程只负责连接
newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);
if(newfd < 0)
{
ERR_MSG("accept");
return -1;
}
printf("[%s : %d] newfd = %d 连接成功\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),newfd);
//创建子进程
pid = fork();
if(pid > 0)
{
close(newfd);
}
else if(0 == pid)
{
close(sfd);
rcv_cli_msg(newfd,cin);
close(newfd);
exit(0);
}
else
{
ERR_MSG("fork");
return -1;
}
}
close(sfd);
return 0;
}
1.h
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
#include <sqlite3.h>
#include <signal.h>
#include <time.h>
#define PORT 8888
#define IP "192.168.8.111"
struct message
{
char head;
char msg[128];
char name[50];
};
#define ERR_MSG(msg) do{\
fprintf(stderr, "__%d__", __LINE__);\
perror(msg);\
}while(0)
typedef void (*sighandler_t)(int);
void handler(int sig);//回收僵尸进程
void word_exist();//初始化判断
int tcp_lianjie();//tcp链接
int rcv_cli_msg(int newfd, struct sockaddr_in cin);//接收客户端信息
int user_up(int newfd,struct sockaddr_in cin,char *msg,sqlite3* db_user);//用户注册
int user_in(int newfd,struct sockaddr_in cin,char *msg,sqlite3* db_user);//用户登录
int search(int newfd,struct sockaddr_in cin,struct message cil_buf,sqlite3* db_word,sqlite3* db_user);//查询
int history(int newfd,struct sockaddr_in cin,struct message cil_buf,sqlite3* db_user);//查历史纪录
int do_select(sqlite3* db,char* table,char* name,char* buf);//查询用户名密码是否正确
int do_insert(sqlite3* db,char* buf);//导入单词
int word_into();//存储数据
int isonline(char* msg,sqlite3* db_user);//判断用户是否在线
int log_out(char* name,sqlite3* db_user);//退出登入
#endif
功能函数
#include "1.h"
void handler(int sig)
{
//回收僵尸进程
while(waitpid(-1, NULL, WNOHANG) > 0);
}
//初始化判断
void word_exist()
{
//导入单词到数据库
if(access("./word.db",F_OK) == 0)
{
printf("单词数据库已存在\n");
}
else
{
if(access("./dict.txt",F_OK) == -1)
{
printf("存储单词的文本不存在\n");
exit(0);
}
else
{
printf("正在导入单词\n");
word_into();
printf("单词数据库导入成功\n");
}
}
//创建用户数据库
if(access("./user.db",F_OK) == 0)//数据库已经存在
{
return;
}
//打开数据库
printf("正在创建用户数据库\n");
sqlite3* db_user = NULL;
if(sqlite3_open("./user.db", &db_user) != SQLITE_OK)
{
printf("errmsg:%s\n", sqlite3_errmsg(db_user));
fprintf(stderr, "__%d__ sqlite3_open failed\n", __LINE__);
exit(0);
}
//创建一个用户表格
char* sql = "create table if not exists user (name char primary key, password char,online char);" ;
char* errmsg = NULL;
if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
exit(0);
}
//关闭数据库
sqlite3_close(db_user);
printf("用户数据库创建成功\n");
return;
}
int word_into()
{
char buf[100];
//打开文件
FILE*fd = fopen("./dict.txt","r");
if(NULL == fd)
{
perror("fopen");
return -1;
}
//打开数据库
sqlite3* db_word = NULL;
if(sqlite3_open("./word.db",&db_word) != SQLITE_OK)
{
printf("errmsg:%s\n",sqlite3_errmsg(db_word));
fprintf(stderr,"__%d__ sqlite3_open failed\n",__LINE__);
return -1;
}
//创建一个表格
char sql[128] = "create table if not exists word (word char,mean char)";
char* errmsg = NULL;
if(sqlite3_exec(db_word,sql,NULL,NULL,&errmsg) != SQLITE_OK)
{
fprintf(stderr,"__%d__ sqlite3_exec:%s\n",__LINE__,errmsg);
return -1;
}
//读取文件内容存储到表格中
while(1)
{
if(NULL == fgets(buf,sizeof(buf),fd))//获取一行的内容
break;
do_insert(db_word,buf);
}
sqlite3_close(db_word);
fclose(fd);
return 0;
}
//将单词插入到数据库中
int do_insert(sqlite3* db,char* buf)
{
char word[50] = "",mean[50] = "";
char* q = buf;
int num = 0;
char* errmsg = NULL;
char sql[128] = "";
//获取一行中的单词,遇到二个空格单个单词结束
while(1)
{
if(*q == ' ' && *(q+1) == ' ')
{
while(1)
{
if(*q != ' ')//将q指向下个不是空格的位置,即词性的开头
break;
q++;
}
break;
}
word[num] = *q;
num++;
q++;
}
//q指向后面内容就是单词词性和中文,直接拷贝到mean字符串中
q[strlen(q)-1] = 0;
strcpy(mean,q);
sprintf(sql,"insert into word values(\"%s\",\"%s\")",word,mean);//存入到表中
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
{
fprintf(stderr,"__%d__ sqlite3_exec:%s\n",__LINE__,errmsg);
return -1;
}
return 0;
}
//TCP连接
int tcp_lianjie()
{
int sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd < 0)
{
ERR_MSG("socket");
exit(0);
}
//允许端口快速重用
int reuse = 1;
if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
{
ERR_MSG("setsockopt");
exit(0);
}
//填充地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
//将地址信息结构体绑定到套接字上
if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
{
ERR_MSG("bind");
exit(0);
}
//将套接字设置为被动监听状态,让内核去监听是否有客户端连接;
if(listen(sfd, 10) < 0)
{
ERR_MSG("listen");
exit(0);
}
//打开数据库
sqlite3* db_user = NULL;
if(sqlite3_open("./user.db",&db_user) != SQLITE_OK)
{
printf("errmsg:%s\n",sqlite3_errmsg(db_user));
fprintf(stderr,"__%d__ sqlite3_open failed\n",__LINE__);
return -1;
}
//修改所有用户为非在线状态
char sql[128] = "update user set online=\"N\"";
char* errmsg = NULL;
if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
return -1;
}
//关闭数据库
sqlite3_close(db_user);
return sfd;
}
//接收客户端信息
int rcv_cli_msg(int newfd, struct sockaddr_in cin)
{
//打开存储用户信息的数据库
sqlite3* db_user = NULL;
if(sqlite3_open("./user.db",&db_user) != SQLITE_OK)
{
printf("errmsg:%s\n",sqlite3_errmsg(db_user));
fprintf(stderr,"__%d__ sqlite3_open failed\n",__LINE__);
return -1;
}
//打开存储单词的数据库
sqlite3* db_word = NULL;
if(sqlite3_open("./word.db",&db_word) != SQLITE_OK)
{
printf("errmsg:%s\n",sqlite3_errmsg(db_word));
fprintf(stderr,"__%d__ sqlite3_open failed\n",__LINE__);
return -1;
}
struct message buf;
ssize_t res = 0;
char name[50] = "";
while(1)
{
memset(&buf,0, sizeof(buf));
//循环接收
res = recv(newfd, &buf, sizeof(buf), 0);
if(res < 0)
{
ERR_MSG("recv");
return -1;
}
else if(0 == res)
{
printf("[%s : %d] newfd = %d 断开连接\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),newfd);
//修改用户为非在线状态
char sql[128] = "";
sprintf(sql, "update user set online=\"N\" where name=\"%s\";", name);
char* errmsg = NULL;
if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
return -1;
}
//关闭数据库
sqlite3_close(db_user);
sqlite3_close(db_word);
return 0;
}
switch (buf.head)
{
case 'Z':
//用户注册
user_up(newfd,cin,buf.msg,db_user);
break;
case 'D':
//用户登录
user_in(newfd,cin,buf.msg,db_user);
strcpy(name,buf.msg);
break;
case 'C':
//查询单词
search(newfd,cin,buf,db_word,db_user);
break;
case 'H':
//查历史记录
history(newfd,cin,buf,db_user);
break;
case 'Q':
//退出登录
log_out(name,db_user);
break;
default:
printf("buf.head = %c \t客户端错误\n",buf.head);
}
}
return 0;
}
//用户注册
int user_up(int newfd,struct sockaddr_in cin,char *msg,sqlite3* db_user)
{
printf("用户请求注册\n");
struct message buf;
buf.head = 'Z';
strcpy(buf.msg,"注册成功\n");
char sql[128] = "";
sprintf(sql, "insert into user values(\"%s\", \"%s\",\"%s\");",msg,(msg+strlen(msg)+1),"N");
char* errmsg = NULL;
if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
if(sqlite3_errcode(db_user) == 19)
{
printf("用户名[%s]重复注册\n",msg);
//重复注册
buf.head = 'F';
strcpy(buf.msg,"用户名重复\n");
//发送给客户端
if(send(newfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
return -1;
}
return -1;
}
fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
}
//创建一张表存储历史记录
sprintf(sql,"create table if not exists %s (word char,mean char,time char);",msg);
if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
return -1;
}
printf("用户名[%s]注册成功\n",msg);
//发送给客户端
if(send(newfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
return -1;
}
return 0;
}
//用户登录
int user_in(int newfd,struct sockaddr_in cin,char *msg,sqlite3* db_user)
{
char name[50] = "";
char password[50] = "";
sprintf(name,"name='%s'",msg);
struct message buf;
printf("用户请求登录\n");
buf.head = 'D';
strcpy(buf.msg,"登录成功\n");
//查询用户名密码是否正确
if(do_select(db_user,"user",name,password) == 0)
{
if(isonline(msg,db_user) != 0)
{
printf("用户名[%s]重复登录\n",msg);
buf.head = 'F';
strcpy(buf.msg,"重复登录\n");
//发送给客户端
if(send(newfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
return -1;
}
return 0;
}
}
if(do_select(db_user,"user",name,password) == -1)
{
//用户名错误
buf.head = 'F';
strcpy(buf.msg,"用户名不存在\n");
printf("用户名[%s]不存在\n",msg);
}
else if(strcmp(password,msg+strlen(msg)+1) != 0)
{
//密码错误
buf.head = 'F';
strcpy(buf.msg,"密码错误\n");
printf("用户名[%s]密码错误\n",msg);
}
else
{
printf("用户名[%s]登录成功\n",msg);
//修改用户为在线状态
char sql[128] = "";
sprintf(sql, "update user set online=\"Y\" where name=\"%s\";", msg);
char* errmsg = NULL;
if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
return -1;
}
}
//发送给客户端
if(send(newfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
return -1;
}
}
//判断用户是否在线
int isonline(char* msg,sqlite3* db_user)
{
//判断是否在线,N不在线,Y在线
char sql[128] = "";
char ** pres = NULL; //存储查询结果的首地址
int row, column; //查询结果的行列数
char* errmsg = NULL;
sprintf(sql,"select * from user where name=\"%s\"",msg);
if(sqlite3_get_table(db_user, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
return -1;
}
//能运行到当前位置则说明,查询函数运行成功
if(strcmp(pres[5],"Y") == 0)
{
//释放获取到的空间
sqlite3_free_table(pres);
pres = NULL;
return -1;
}
//释放获取到的空间
sqlite3_free_table(pres);
pres = NULL;
return 0;
}
//查询数据库的单词意思和用户名
int do_select(sqlite3* db,char* table,char* name,char* buf)
{
char sql[128] = "";
char ** pres = NULL; //存储查询结果的首地址
int row, column; //查询结果的行列数
char* errmsg = NULL;
sprintf(sql,"select * from %s where %s;",table,name);
if(sqlite3_get_table(db, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
return -1;
}
if(column == 0)//没有相关的单词或者用户名
{
printf("没有查询到\n");
return -1;
}
strcpy(buf,pres[column+1]);
//释放获取到的空间
sqlite3_free_table(pres);
pres = NULL;
return 0;
}
//用户请求查词
int search(int newfd,struct sockaddr_in cin,struct message cil_buf,sqlite3* db_word,sqlite3* db_user)
{
printf("用户[%s]请求查词\n",cil_buf.name);
struct message buf;
buf.head = 'C';
//将单词和意思保存
char word[150] = "";
char mean[150] = "";
sprintf(word,"word='%s'",cil_buf.msg);
//调用查找函数查找单词
if(do_select(db_word,"word",word,mean) == -1)
{
//单词不存在
buf.head = 'F';
strcpy(buf.msg,"单词不存在\n");
printf("单词[%s]不存在\n",cil_buf.msg);
}
else
{
printf("单词[%s]查询成功,解释[%s]\n",cil_buf.msg,mean);
strcpy(buf.msg,mean);
}
//发送给客户端
if(send(newfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
return -1;
}
//存储单词查询的记录
if(buf.head == 'C')
{
char ti[30] = "";
time_t t = time(NULL);
struct tm *info = NULL;
info = localtime(&t);
//拼接时间
sprintf(ti,"%d-%02d-%02d %02d:%02d:%02d",info->tm_year+1900, info->tm_mon+1, info->tm_mday,info->tm_hour, info->tm_min, info->tm_sec);
char sql[256] = "";
sprintf(sql, "insert into %s values(\"%s\", \"%s\",\" %s\");",cil_buf.name,cil_buf.msg,mean,ti);
char* errmsg = NULL;
if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
return -1;
}
printf("查词[%s]记录存储成功\n",cil_buf.msg);
}
}
//查询历史记录
int history(int newfd,struct sockaddr_in cin,struct message cil_buf,sqlite3* db_user)
{
printf("用户[%s]请求查词历史记录\n",cil_buf.name);
struct message buf;
char his[128] = "";
buf.head = 'H';
//查找数据的内容
char sql[128] = "select * from stu";
char ** pres = NULL; //存储查询结果的首地址
int row, column; //查询结果的行列数
char* errmsg = NULL;
sprintf(sql,"select * from %s",cil_buf.name);
if(sqlite3_get_table(db_user, sql, &pres, &row, &column, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
return -1;
}
//能运行到当前位置则说明,查询函数运行成功
int i = 0;
ssize_t res;
for(i=0; i<(row+1)*column; i++)
{
strcat(his,pres[i]);
strcat(his,"|");
if(i%column == (column-1))
{
strcpy(buf.msg,his);
if(send(newfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
return -1;
}
bzero(his,sizeof(his));
res = recv(newfd,&buf,sizeof(buf),0);
if(res < 0)
{
ERR_MSG("recv");
return -1;
}
else if(res == 0)
{
printf("客户端退出\n");
return 0;
}
if(buf.head != 'H')
{
printf("客户端异常\n");
return -1;
}
}
}
buf.head = 'F';
if(send(newfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
return -1;
}
//释放获取到的空间
sqlite3_free_table(pres);
pres = NULL;
return 0;
}
//退出登录,修改数据库信息为N
int log_out(char* name,sqlite3* db_user)
{
printf("用户[%s]退出登录\n",name);
//修改用户为非在线状态
char sql[128] = "";
sprintf(sql, "update user set online=\"N\" where name=\"%s\";",name);
char* errmsg = NULL;
if(sqlite3_exec(db_user, sql, NULL, NULL, &errmsg) != SQLITE_OK)
{
fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
return -1;
}
return 0;
}
客户端:
mian.c
#include "1.h"
int main(int argc, const char *argv[])
{
//创建流式套接字
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd < 0)
{
ERR_MSG("socket");
return -1;
}
//填充要连接的服务器的地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
//连接服务器
if(connect(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
{
ERR_MSG("connect");
return -1;
}
printf("连接成功服务器\n");
struct message buf;
int choose;
int num;
while(1)
{
menu(1);
scanf("%d",&choose);
while(getchar() != 10);
switch(choose)
{
case 1:
//注册
user_up(sfd);
break;
case 2:
//登录
num = user_in(sfd);
break;
case 3:
//退出
system("clear");
exit(0);
default:
printf("输入错误\n");
}
}
return 0;
}
头文件
#ifndef __1_H__
#define __1_H__
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string.h>
//打印错误新的宏函数
#define ERR_MSG(msg) do{\
fprintf(stderr, " __%d__ ", __LINE__);\
perror(msg);\
}while(0)
//发送接收结构体
struct message
{
char head;
char msg[128];
char name[50];
};
//指定要连接的服务器的地址信息
#define PORT 8888
#define IP "192.168.8.111"
void menu(int n);//菜单
int user_up(int sfd);//用户注册
int user_in(int sfd);//用户登录
int word(int sfd,char* user);//调用
int history(int sfd,char* user);//查看历史
int cil_search(int sfd,char* user);//查询
int go_out(int sfd,char* user);//退出登录
#endif
功能函数
#include "1.h"
//菜单函数
void menu(int n)
{
if(1 == n)
{
printf("----------------\n");
printf("-----1.注册-----\n");
printf("-----2.登录-----\n");
printf("-----3.退出-----\n");
printf("----------------\n");
}
else if(2 == n)
{
printf("-----------------\n");
printf("---1.查单词------\n");
printf("---2.历史记录----\n");
printf("---3.返回上一级--\n");
printf("-----------------\n");
}
}
//注册用户
int user_up(int sfd)
{
system("clear");
struct message buf;
buf.head = 'Z';
char user[50] = "";
char password[50] = "";
printf("请输入要注册的用户名user>>>");
scanf("%s",user);
printf("请输入密码password>>>");
scanf("%s",password);
sprintf(buf.msg,"%s%c%s",user,0,password);
if(send(sfd,&buf,sizeof(buf),0) <0)
{
ERR_MSG("send");
return -1;
}
if(recv(sfd,&buf,sizeof(buf),0) < 0)//接收服务器的信息
{
ERR_MSG("recv");
return -1;
}
if(buf.head == 'Z')//'Z'注册成功
{
printf("%s",buf.msg);
printf("您的用户名:%s\n",user);
printf("您的密码:%s\n",password);
}
else if(buf.head == 'F')//'F'没有注册成功
{
printf("%s",buf.msg);
}
return 0;
}
//用户登录
int user_in(int sfd)
{
system("clear");
struct message buf;
buf.head = 'D';
char user[50] = "";
char password[50] = "";
printf("请输入用户名user>>>");
scanf("%s",user);
printf("请输入密码password>>>");
scanf("%s",password);
sprintf(buf.msg,"%s%c%s",user,0,password);
if(send(sfd,&buf,sizeof(buf),0) <0)
{
ERR_MSG("send");
return -1;
}
if(recv(sfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("recv");
return -1;
}
if(buf.head == 'D')//'D'登录成功
{
printf("%s",buf.msg);
}
else if(buf.head == 'F')//'F'登录失败
{
printf("%s",buf.msg);
return -1;//密码错误,用户名或者用户已在线不存在
}
word(sfd,user);//调用查词函数
return 0;
}
//查词历史记录
int word(int sfd,char* user)
{
int choose;
while(1)
{
menu(2);
scanf("%d",&choose);
while(getchar()!=10);
switch(choose)
{
case 1:
cil_search(sfd,user);//查词
break;
case 2:
history(sfd,user);//查看历史记录
break;
case 3:
go_out(sfd,user);//回到上一级
return 0;
default:
printf("输入错误\n");
}
}
}
//查询单词
int cil_search(int sfd,char* user)
{
system("clear");
struct message buf;
char str[128] = "";
buf.head = 'C';
while(1)
{
strcpy(buf.name,user);
buf.head = 'C';
printf("请输入单词(输入#结束查词)>>>");
fgets(str,sizeof(str),stdin);
str[strlen(str)-1] = 0;
if(str[0] == '#')//退出查词
{
system("clear");
break;
}
strcpy(buf.msg,str);
if(send(sfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
return -1;
}
if(recv(sfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("recv");
return -1;
}
if(buf.head == 'F')//F查词失败
{
printf("单词[%s]%s",str,buf.msg);
}
else if(buf.head == 'C')//C查词成功
{
printf("单词:[%s]\t解释:[%s]\n",str,buf.msg);
}
else
{
printf("服务器异常");
break;
}
}
}
//历史记录
int history(int sfd,char* user)
{
system("clear");
int n = 0;
struct message buf;
char* q = buf.msg;
strcpy(buf.name,user);
buf.head = 'H';
if(send(sfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
return -1;
}
while(1)
{
strcpy(buf.name,user);
q = buf.msg;
if(recv(sfd,&buf,sizeof(buf),0) < 0)//接服务器的信息
{
ERR_MSG("recv");
return -1;
}
if(buf.head == 'F')//接收完毕
{
if(n == 1)//n被修改为1,查过词
{
printf("查询完毕\n");
}
else
printf("你还没有查过词\n");
break;
}
else
{
while(*q != '\0')//一个一个字符打印
{
if(*q != '|')
{
printf("%c",*q);
}
else
{
printf("\t\t");//遇到|打印\t
}
q++;
n = 1;
}
printf("\n");
}
if(send(sfd,&buf,sizeof(buf),0) < 0)//发送ASK验证
{
ERR_MSG("send");
return -1;
}
}
}
//退出登录
int go_out(int sfd,char* user)
{
struct message buf;
strcpy(buf.msg,user);
//向服务器发送退出登录信息
buf.head = 'Q';
if(send(sfd,&buf,sizeof(buf),0) < 0)
{
ERR_MSG("send");
return -1;
}
system("clear");
return 0;
}
情况: