用C语言实现“电子词典”项目

实现功能:

项目要求:

  1. 登录注册功能,不能重复登录,重复注册

  2. 单词查询功能

  3. 历史记录功能,存储单词,意思,以及查询时间

  4. 基于TCP,支持多客户端连接

  5. 采用数据库保存用户信息与历史记录

  6. 将dict.txt的数据导入到数据库中保存。

  7. 按下ctrl+c退出客户端后,注销该客户端的登录信息

格式要求:

  1. main函数只跑逻辑,不允许跑功能代码

  2. 功能代码封装成函数

简略框架图:

 

效果展示:

1.登入界面 

        1.1普通登入

        1.2重复登入

        1.3错误登入

2.注册界面 

        2.1普通注册

        2.2重复注册

  

3.单词查询界面

4.数据库

        4.1dict单词数据库

        4.2用户账号密码数据库

        4.3 历史记录数据库 (表对应每个用户)

服务器:

        Serfun.h:

#ifndef __TEST_H__
#define __TEST_H__

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

typedef struct Node
{
	union
	{
		int len;                  //存储头节点数据域,表示结点个数
		struct sockaddr_in cin; 	//数据域,普通结点要存放的值
	};
	char id[20];
	struct Node *next;           //指针域,记录下个结点的地址
}Linklist;

#define ERR_MSG(msg)  do{\
	fprintf(stderr, " __%d__ ", __LINE__);\
	perror(msg);\
}while(0)

//需要传入线程的数据
struct msg
{
	Linklist* L;
	int newfd;
	struct sockaddr_in cin;
};

//用户信息结构体            
struct user_msg             
{    
	char type;
	char id[20];                 
	char password[20];           
};                          

 //查询单词的结构体        
 struct W_ord              
 {                         
     char word[20];        
     char mean[50];    
 };                        
                           


//循环打印已有客户端的线程
void* loop_printf(void* arg);

//将didt单词表添加到 dict.db 数据库中;
int add_dict();

//判断登入注册
int logreg_Interface(sqlite3* userdb,struct user_msg usermsg,int newfd,Linklist* L);

//用户登入函数int user_login(sqlite3* userdb,struct user_msg usermsg,int newfd,Linklist* l);
int user_login(sqlite3* userdb,struct user_msg usermsg,int newfd,Linklist* L);

//用户注册函数
int user_register(sqlite3* userdb,struct user_msg usermsg,int newfd);

//查询对应的单词和解释
int search_word(struct W_ord words,int newfd,struct user_msg usermsg);

//分支线程用户与客户端交互
void* rcv_cli_msg(void* arg);	//void* arg = (void*)&cliInfo

//创建链表
Linklist *list_create();

//头插
int list_intsrt_head(Linklist*L, struct sockaddr_in cin,char id[20]);

//任意删
int list_delete_pos(Linklist *L, char id[20]);

//链表的销毁
void list_free(Linklist *L);

//头删
int list_delete_head(Linklist *L);

//判空
int list_empty(Linklist *L);

//遍历循环打印已有客户端
void list_show(Linklist *L);

//查找用户
int list_search_value(Linklist *L, char id[20]);
#endif

        serfun.c :

#include "serfun.h"                                                                                                                                                                                 
                                                                                                       
//循环打印已有客户端的线程                                                                             
void* loop_printf(void* arg)                                                                           
{                                                                                                      
    Linklist* L = arg;                                                                                 
                                                                                                       
    pthread_detach(pthread_self());                                                                    
    while(1)                                                                                           
    {                                                                                                  
        system("clear");                                                                               
        list_show(L);                                                                                  
        sleep(3);                                                                                      
    }                                                                                                  
                                                                                                       
    pthread_exit(NULL);                                                                                
}                                                                                                      
                                                                                                       
                                                                                                       
                                                                                                       
//线程处理函数                                                                                         
void* rcv_cli_msg(void* arg)    //void* arg = (void*)&cliInfo                                          
{                                                                                                      
    //分离分支线程                                                                                     
    pthread_detach(pthread_self());                                                                    
                                                                                                       
    int newfd = (*(struct msg*)arg).newfd;                                                             
    struct sockaddr_in cin = (*(struct msg*)arg).cin;                                                  
                                                                                                       
    Linklist* L = (*(struct msg*)arg).L;                                                               
                                                                                                       
    //定义结构体:接收客户端发来的用户信息                                                             
    struct user_msg usermsg;                                                                           
                                                                                                       
    //创建用户数据库                                                                                   
    sqlite3* userdb = NULL;                                                                            
    if(sqlite3_open("./user.db", &userdb) != SQLITE_OK)                                                
    {                                                                                                  
        fprintf(stderr, "__%d__ sqlite3_open failed\n", __LINE__);                                     
        return NULL;                                                                                   
    }                                                                                                  
                                                                                                       
    //创建用户数据库账号密码表                                                                         
    char* sql = "create table if not exists userMsg (id char primary key, password char);" ;           
    char* errmsg = NULL;                                                                               
    if(sqlite3_exec(userdb, sql, NULL, NULL, &errmsg) != SQLITE_OK)                                          
    {                                                                                                        
        fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);                                       
        return NULL;                                                                                         
    }                                                                                                        
                                                                                                             
                              	while(1)
	{
		//接收登入、注册信息
		ssize_t res;
		res = recv(newfd, &usermsg, sizeof(usermsg), 0);                                                                     
		if(res < 0)                                                                                                 
		{                                                                                                           
			ERR_MSG("recv");                                                                                        
			return NULL;                                                                                               
		}                                                                                                           
		else if(0 == res)                                                                                           
		{                                                                                                           
			printf("[%s : %d] newfd = %d 客户端掉线\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),newfd);
			list_delete_pos(L,usermsg.id);
			close(newfd);
			pthread_exit(NULL);
			break;
		}                                                                                                           

		if( logreg_Interface(userdb,usermsg,newfd,L) == 1 ) //1函数成功 -2函数重新需要参数执行
		{
			break;	
		}
	}

	//将网络结构体插入链表
	list_intsrt_head(L,cin,usermsg.id);

	struct W_ord words;
	char buf[128] = "";
	ssize_t res = 0;
	while(1)
	{
		bzero(&words,sizeof(words));
		bzero(buf, sizeof(buf));
		//循环接收 
		res = recv(newfd, &words, sizeof(words), 0);
		if(res < 0)
		{
			ERR_MSG("recv");
			break;
		}
		else if(0 == res)
		{
			printf("[%s : %d] newfd = %d 客户端掉线\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),newfd);
			list_delete_pos(L,usermsg.id);
			break;
		}

		//查询对应的单词和解释
		search_word(words,newfd,usermsg);

	}
	close(newfd);
	
	pthread_exit(NULL);
}


//判断用户登入注册
int logreg_Interface(sqlite3* userdb,struct user_msg usermsg,int newfd,Linklist* L)
{

	if(usermsg.type == 'L')
	{
		return user_login(userdb,usermsg,newfd,L);   //1函数成功 -2函数重新需要参数执行
	}
	else if(usermsg.type == 'R')
	{
		return user_register(userdb,usermsg,newfd); //2为函数运行成功
	}
	
	return 0;
}

//用户登入函数
int user_login(sqlite3* userdb,struct user_msg usermsg,int newfd,Linklist* L)
{

	//查询账号密码是否在数据库中
	char cmp[128] = "";
	sprintf(cmp,"SELECT * FROM userMsg WHERE id like \"%s\" AND password like \"%s\"",usermsg.id,usermsg.password);
	char ** pres = NULL;
	int row,column;     //查询结果的行列数
	char * errmsg = NULL;
	if(sqlite3_get_table(userdb, cmp, &pres, &row, &column, &errmsg) != SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
		return -1;
	}

	//发送给客户端确认信息, 1为成功,-1为账号密码错误,-2为已经登入
	int flag = 0;
	if(list_search_value(L,usermsg.id) != 0)
	{
		flag = -2;
		if(send(newfd, &flag, sizeof(flag), 0) < 0)
		{
			ERR_MSG("send");
			return -1;
		}
		return -2;
	}

	if(row == 1)   //账号密码在数据库
	{
		flag = 1;
		if(send(newfd, &flag, sizeof(flag), 0) < 0)
		{
			ERR_MSG("send");
			return -1;
		}
		printf("%s用户登入成功\n",usermsg.id);
		return 1;
	}
	else
	{
		flag = -1;
		if(send(newfd, &flag, sizeof(flag), 0) < 0)
		{
			ERR_MSG("send");
			return -1;
		}
		return -2;
	}

	//释放获取到的空间
	sqlite3_free_table(pres);
	pres = NULL;

	return 0;
}


//用户注册函数
int user_register(sqlite3* userdb,struct user_msg usermsg,int newfd)
{
	int flag = 1 ;  //注册成功为1,注册失败为-1;

	//调用插入数据库
	char* errmsg = NULL;
	char msg[128] = "";
	sprintf(msg, "insert into userMsg values(\"%s\",\"%s\")", usermsg.id,usermsg.password);
	if(sqlite3_exec(userdb, msg, NULL, NULL, &errmsg) != SQLITE_OK)
	{
		flag = -1; //注册失败,发送-1给客户端
		fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__,errmsg);
		if(send(newfd, &flag, sizeof(flag), 0) < 0)
		{
			ERR_MSG("send");
			return -2;
		}
		return -2;
	}

	//注册成功,发送1给客户端
	if(send(newfd, &flag, sizeof(flag), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}
	printf("%s用户注册成功\n",usermsg.id);

	return 2;
}


//查询对应的单词和解释,并发送给客户端,并加入历史记录
int search_word(struct W_ord words,int newfd,struct user_msg usermsg)
{
	//打开单词数据库
	sqlite3* dictdb = NULL;
	if(sqlite3_open("./dict.db", &dictdb) != SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_open:%s\n", __LINE__, sqlite3_errmsg(dictdb));
		return -1;
	}

	//打开所有用户的历史记录数据库
	sqlite3* histroy = NULL;
	if(sqlite3_open("./histroy.db", &histroy) != SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_open failed\n", __LINE__);
		return -1;
	}

	//创建对应用户的历史记录表格
	char sql[128] = "";
	sprintf(sql,"create table if not exists %s (word char, mean char,time char);",usermsg.id);
	char* errmsg = NULL;
	if(sqlite3_exec(histroy, sql, NULL, NULL, &errmsg) != SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
		return -1;
	}


	//查询单词和解释是否在数据库中
	char cmp[128] = "";

	//将命令存入cmp, word像xxx或者意思像xxx的
	sprintf(cmp,"SELECT * FROM dict WHERE word like \"%s\" OR mean like \" %s \"",words.word,words.mean);

	char ** pres = NULL;
	int row,column;     //查询结果的行列数
	if(sqlite3_get_table(dictdb, cmp, &pres, &row, &column, &errmsg) != SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_get_table:%s\n", __LINE__, errmsg);
		return -1;
	}

	//判断是否查找到
	if(row == 0)
	{
		strcpy(words.mean,"未找到此单词");
	}
	else
	{
		//将查到的数据存入单词结构体
		bzero(&words,sizeof(words));
		strcpy(words.word,pres[2]);
		strcpy(words.mean,pres[3]);

		//获取查询时间
		time_t t;
		struct tm *info = NULL;
		char timenow[128] = "";
		t = time(NULL);
		info = localtime(&t);
		sprintf(timenow, "%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);

		//将单词存入历史记录表
		bzero(sql,sizeof(sql));
		sprintf(sql, "insert into %s values(\"%s\",\"%s\",\"%s\");", usermsg.id,pres[2],pres[3],timenow);
		if(sqlite3_exec(histroy, sql, NULL, NULL, &errmsg) != SQLITE_OK)
		{
			fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__, errmsg);
			return -1;
		}
	}

	//将结构体发送给客户端
	if(send(newfd, &words, sizeof(words), 0) < 0)
	{
		ERR_MSG("send");
		return -1;
	}

	//关闭数据库
	sqlite3_close(dictdb);
	return 0;
}



//将didt单词表添加到 dict.db 数据库中;
int add_dict()
{
	//打开数据库
	sqlite3* dictdb = NULL;
	if(sqlite3_open("./dict.db", &dictdb) != SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_open:%s\n", __LINE__, sqlite3_errmsg(dictdb));
		return -1;
	}

	char sql[400] = "create table if not exists dict (word char, mean char)";
	char* errmsg = NULL;
	//创建表格
	if(sqlite3_exec(dictdb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
	{
		fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__,errmsg);
		return -1;
	}


	//打开文件
	FILE* fp = fopen("./dict.txt", "r");
	if(NULL == fp)
	{
		perror("fopen");
		return -1;
	}

	//循环读取一行,直到读取完毕为止
	char buf[300] = "";
	char word[50]="", mean[300]="";
	int i = 0;

	while(fgets(buf, sizeof(buf), fp) != NULL)
	{
		buf[strlen(buf)-1] = 0;
		//分离单词和意思
		for(i=0; i<strlen(buf)-2; i++)
		{
			if(buf[i]!=' ' && buf[i+1]==' ' && buf[i+2]==' ')
			{
				strncpy(word, buf, i+1);
				//			printf("wrod = %s\n", word);
			}
			else if(buf[i]==' '&& buf[i+1]==' ' && buf[i+2]!=' ')
			{
				strcpy(mean, (buf+i+2));
				break;
			}
		}

		//插入到数据库中
		sprintf(sql, "insert into dict values(\"%s\", \"%s\")", word, mean);
		//	printf("%s\n", sql);
		if(sqlite3_exec(dictdb, sql, NULL, NULL, &errmsg) != SQLITE_OK)
		{
			fprintf(stderr, "__%d__ sqlite3_exec:%s\n", __LINE__,errmsg);
			return -1;
		}

		bzero(word, sizeof(word));
		bzero(mean, sizeof(mean));
	}
	printf("导入单词库成功\n");
	//关闭文件
	fclose(fp);
	//关闭数据库
	sqlite3_close(dictdb);
}

//创建链表
Linklist *list_create()
{
	Linklist* L = (Linklist*)malloc(sizeof(Linklist));
	if(NULL == L)
	{
		printf("创建失败\n");
		return NULL;
	}

	//初始化
	L->next = NULL;
	L->len = 0;
	return L;
}

//头插
int list_intsrt_head(Linklist*L, struct sockaddr_in cin,char id[20])
{
	//申请节点
	Linklist *p = (Linklist*)malloc(sizeof(Linklist));
	if(NULL==p)
	{
		printf("节点申请失败\n");
		return -1;
	}

	//将要插入的数据放入节点
	p->cin = cin;
	p->next = NULL;
	strcpy(p->id,id);

	//完成头插
	p->next = L->next;
	L->next = p;

	//表的变化
	L->len++;

	printf("头插成功\n");
	return 0;
}


//任意删
int list_delete_pos(Linklist *L, char id[20])
{
	//判断逻辑
	if(NULL==L || list_empty(L) )
	{
		return -1;
	}	
	
	
	Linklist *q = L;
	if(strcmp(q->next->id,id))
	{
		q = q->next;
	}

	//删除逻辑
	Linklist *p = q->next;
	q->next = p->next;
	free(p);
	p = NULL;

	//表的变化
	L->len --;

	return 0;
}


//链表的销毁
void list_free(Linklist *L)
{
	if(NULL == L)
	{
		return;
	}

	//不断调用头删,将结点进行删除
	while(L->next != NULL)
	{
		list_delete_head(L);
	}

	//将头结点释放
	free(L);
	L = NULL;

	printf("释放表完成\n");
	return ;
}

//头删
int list_delete_head(Linklist *L)
{
	//判断逻辑
	if(NULL==L || list_empty(L))
	{
		printf("删除失败\n");
		return -1;
	}

	//头删
	Linklist *p = L->next;    //标记
	L->next = p->next;        //孤立
	free(p);                  //踢开
	p=NULL;

	//表的变化
	L->len--;
	return 0;
}

//判空
int list_empty(Linklist *L)
{
	//1表示空   0表示非空
	if(NULL==L)
	{
		printf("表不合法\n");
		return -1;
	}
	return NULL==L->next ? 1:0;
}


//遍历循环打印已有客户端
void list_show(Linklist *L)
{
	//判断逻辑
	if( NULL==L || list_empty(L))
	{
		printf("还未有客户端用户登入(3s更新一次)\n");
		return;
	}

	//遍历逻辑
	printf("在线的客户端数量为%d,用户分别为(3s更新一次):\n",L->len);
	Linklist *q = L->next;
	while(q != NULL)
	{
		printf("地址:[%s : %d]\t用户名:[%s]\n", inet_ntoa(q->cin.sin_addr), ntohs(q->cin.sin_port),q->id);
		q = q->next;
	}
	printf("\n");
}


//查找用户
int list_search_value(Linklist *L, char id[20])
{
	//查找逻辑
	Linklist *q = L->next;
	for(int i=1; i<=L->len; i++)
	{
		if(strcmp(q->id,id))
		{
			q = q ->next;
		}
		else
		{
			return i;
		}
	}

	return 0;
}
                                      

        main.c:

#include "serfun.h"

#define PORT 8888 				//1024~49151
#define IP 	"192.168.31.188" 	//本机IP,用ifconfig查看

int main(int argc, const char *argv[])
{
	//创建套接字
	int sfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("create socket success\n");

	//允许端口快速重用
	int reuse = 1;
	if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}

	//填充地址信息结构体,真实的地址信息结构体与协议族相关
	//AF_INET,所以详情请看man 7 ip
	struct sockaddr_in sin;
	sin.sin_family 		= AF_INET;
	sin.sin_port 		= htons(PORT); 	//网络字节序的端口号
	sin.sin_addr.s_addr = inet_addr(IP); 	//网络字节序的IP地址

	//将地址信息结构体绑定到套接字上
	if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind success\n");

	//将套接字设置为被动监听状态,让内核去监听是否有客户端连接;
	if(listen(sfd, 10) < 0)
	{
		ERR_MSG("listen");
		return -1;
	}
	printf("listen success\n");

	system("clear");

	//创建存储客户端网络结构体链表
	Linklist *L = list_create();
	if(NULL == L)
	{
		return -1;
	}
	//定义存储客户端网络结构体
	struct sockaddr_in cin;
	socklen_t addrlen = sizeof(cin);

	//将didt单词表添加到 dict.db 数据库中;
	add_dict();

	int newfd = 0;
	pthread_t tid;
	struct msg cliInfo;
	//从已完成连接的队列头中,取出一个客户端的信息,创建生成一个新的套接字文件描述符,
	//该文件描述符才是与客户端通信的文件描述符!!!

	//循环打印已有客户端的线程
	if(pthread_create(&tid, NULL, loop_printf, (void*)L) != 0)
	{
		ERR_MSG("pthread_create");
		return -1;
	}

	while(1)
	{
		//主线程主要负责连接
		newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);
		if(newfd < 0)
		{
			perror("accept");
			return -1;
		}

		//网络字节序的IP-->点分十进制  网络字节序的port--->本机字节序
		printf("[%s : %d] newfd = %d 客户端连入\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),newfd);

		cliInfo.newfd = newfd;
		cliInfo.cin = cin;
		cliInfo.L = L;


		//一旦连接成功后,创建一个分支线程用户与客户端交互;
		if(pthread_create(&tid, NULL, rcv_cli_msg, (void*)&cliInfo) != 0)
		{
			ERR_MSG("pthread_create");
			return -1;
		}
	}

	close(sfd);
	list_free(L);
	return 0;
}

客户端:

        clifun.h:

#ifndef __CLIFUN_H__
#define __CLIFUN_H__

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

#define ERR_MSG(msg)  do{\
	fprintf(stderr, " __%d__ ", __LINE__);\
	perror(msg);\
}while(0)

//需要传入线程的数据
struct msg
{
	int newfd;
	struct sockaddr_in cin;
};

//用户信息结构体
struct user_msg
{
	char type;
	char id[20];
	char password[20];
};

//查询单词的结构体
struct W_ord
{
	char word[20];
	char mean[50];
};

struct PRES               
{                         
	char ** topres;       
};                        
     

//将didt单词表添加到 dict.db 数据库中;
int add_dict(sqlite3*);

//登入注册界面
int logreg_Interface(int sfd);

//向服务器发送用户登入申请
int user_login(int sfd);

//向服务器发送用户注册申请
int user_register(int sfd);


//分支线程用户与客户端交互
void* rcv_cli_msg(void* arg);	//void* arg = (void*)&cliInfo


#endif

         clifun.c:

#include "clifun.h"

//登入注册界面
int logreg_Interface(int sfd)
{
	while(1)
	{
		printf("-----------洪氏宝典----------\n");
		printf("-----------1.登入------------\n");
		printf("-----------2.注册------------\n");
		printf("-----------3.退出------------\n");

		int num; //存储选择的序号
		printf("请选择:");
		scanf("%d",&num);

		if(num == 1)
		{
			if(user_login(sfd) == -1)
			{
				return -1;
			}
			else
			{
				break;
			}
		}
		else if(num == 2)
		{
			if(user_register(sfd) == -1)
			{
				return -1;
			}
			if(user_login(sfd) == -1)
			{
				return -1;
			}
			break;
		}
		else if(num == 3)
		{
			return -2;
		}
		else
		{
			printf("选择无效,请重新选择\n");
		}
	}
	return 0;
}

//向服务器发送用户登入申请
int user_login(int sfd)
{
	while(1)
	{
		printf("------登入------\n");
		//填入账号密码数据
		struct user_msg usermsg;
		usermsg.type = 'L';
		printf("请输入账号:");
		scanf("%s",usermsg.id);
		getchar();
		printf("请输入密码:");
		scanf("%s",usermsg.password);
		getchar();

		//发送给服务器
		if(send(sfd, &usermsg , sizeof(usermsg), 0) < 0)
		{
			ERR_MSG("send");
			return -1;
		}

		//接受服务器发来的确认信息	
		int flag;
		ssize_t res;
		res = recv(sfd, &flag, sizeof(flag), 0);
		if(res < 0)
		{
			ERR_MSG("recv");
			return -1;
		}
		else if(0 == res)
		{
			return -1;
		}

		//判断服务器发来的确认信息 1为成功,-1为失败(数据错误)
		if(flag == 1)
		{
			printf("登入成功\n");
			break;
		}
		else if(flag == -1)
		{
			printf("用户账号密码错误\n");
		}
		else if(flag == -2)
		{
			printf("该用户已经登入\n");
		}
	}
	return 0;
}


//向服务器发送用户注册申请
int user_register(int sfd)
{
	printf("------注册------\n");
	while(1)
	{
		//填入要注册账号密码数据
		struct user_msg usermsg;
		usermsg.type = 'R';
		printf("请输入注册账号(不能纯数字):");
		scanf("%s",usermsg.id);
		getchar();
		printf("请输入注册密码:");
		scanf("%s",usermsg.password);
		getchar();

		//发送给服务器
		if(send(sfd, &usermsg , sizeof(usermsg), 0) < 0)
		{
			ERR_MSG("send");
			return -1;
		}

		//接受服务器发来的确认信息	
		int flag;
		ssize_t res;
		res = recv(sfd, &flag, sizeof(flag), 0);
		if(res < 0)
		{
			ERR_MSG("recv");
			return -1;
		}
		else if(0 == res)
		{
			printf("server is off-line\n");
			return -1;
		}

		//判断服务器发来的确认信息 1为成功,-1为失败(数据错误)
		if(flag == 1)
		{
			printf("注册成功\n");
			break;
		}
		else if(flag < 0)
		{
			printf("注册失败,重复注册\n");
		}
	}
	return 0;
}

         cli.c:

#define PORT 8888                                    
#define IP  "192.168.31.188"  

int main(int argc, const char *argv[])
{

	//创建流式套接字
	int sfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sfd < 0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("create socket success\n");


	//绑定客户端的地址信息结构体--》非必须绑定 
	
	//填充要连接的服务器的地址信息结构体
	struct sockaddr_in sin;
	sin.sin_family 		= AF_INET;
	sin.sin_port 		= htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);

	//连接服务器 connect
	if(connect(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
	{
		ERR_MSG("connect");
		return -1;
	}

	int reslog;
	reslog = logreg_Interface(sfd);
	if(reslog== 0)
	{
	
	}
	else if(reslog == -1)
	{
		printf("服务器掉线\n");
		return -1;
	}
	else
	{
		return -1;
	}

	system("clear");
	//查询单词操作
	char buf[128] = "";
	ssize_t res = 0;
	struct W_ord words = {"",""};
	struct PRES sinpres;
	while(1)
	{
		bzero(&words,sizeof(words));
		bzero(buf, sizeof(buf));
		//发送
		printf("请输入要查询的单词>>>");
		fgets(buf, sizeof(buf), stdin);
		buf[strlen(buf)-1] = 0;
	
		//判断输入的是单词还是解释
		if(buf[0] > 0) //如果第一个是字母的话
		{
			strcpy(words.word,buf); //将输入存到word里面
		}
		else
		{
			strcpy(words.mean,buf);//如果不是将输入存到explain里面
		}

		if(send(sfd, &words, sizeof(words), 0) < 0)
		{
			ERR_MSG("send");
			return -1;
		}

		//接收 
		bzero(&words, sizeof(words));
		res = recv(sfd, &words, sizeof(words), 0);
		if(res < 0)
		{
			ERR_MSG("recv");
			return -1;
		}
		else if(0 == res)
		{
			printf("服务器已掉线\n");
			break;
		}
		printf("%s\t%s\n", words.word, words.mean);
	}

	//关闭套接字
	close(sfd);

	return 0;
}

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值