day??? 网络编程 另一个小项目 c语言

3.项目:基于TCP的文件服务
项目需求:
1.编写客户端和服务器
2客户端可以查看服务器端目录中的文件名 opendir readdir
3客户端可以从服务器中下载文件
4客户端可以上传文件给服务器

头文件

#ifndef __DIC_H__
#define __DIC_H__

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <dirent.h>
#include <fcntl.h>

#define MAXSIZE 512

#define ERR_MSG(msg)do{\
	fprintf(stderr,"%s failed at line %d.\n",msg,__LINE__);\
}while(0)

#define SUC_MSG(msg)do{\
	printf("%s success at line %d.\n",msg,__LINE__);\
}while(0)

//socket related
void create_socket(int*);
void quick_reuse(int*);
void bind_socket(int*,struct sockaddr_in*,int*,int,const char*);
void listen_socket(int*);
void connect_server(int*,struct sockaddr_in*,socklen_t,int,const char*);
int accept_socket(int,struct sockaddr_in*,socklen_t*);

#endif

服务器端

#include "dir.h"

const int serPort = 2305;
const char* serIp = "192.168.10.104";

void zombie_deal(int);
void reveal_content(int,char*);
void show_dir(int);
void recv_from_cli(int);
void deal_client(int,struct sockaddr_in);

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

	int sfd;
	struct sockaddr_in sin;
	int len = sizeof(sin);

	struct sockaddr_in cin;
	int newfd;

	//if a child process dies
	if(signal(17,zombie_deal) == SIG_ERR){
		ERR_MSG("Receive signal");
		return -1;
	}

	//create socket 
	create_socket(&sfd);
	//allow quick reuse of port
	quick_reuse(&sfd);
	//bind socket
	bind_socket(&sfd,&sin,&len,serPort,serIp);
	//turn the socket sfd into a listen fd
	listen_socket(&sfd);

	while(1){
		//create a new fd if a client successfully connected
		newfd = accept_socket(sfd,&cin,&len);

		if(fork() == 0){

			deal_client(newfd,cin);

			close(sfd);
			
		}
		else{
		//每次fork后,cin加入数组,cpid
		}

		close(newfd);
	}

	close(sfd);

	return 0;
}

客户端

#include "dic.h"

const int serPort = 2305;
const char* serIp = "192.168.10.104";

void upload_files(int);
int open_file();
void view_files(int,int);
void show_menu(int);

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

	int sfd;
	struct sockaddr_in sin;
	int len = sizeof(sin);

	//create socket 
	create_socket(&sfd);

	//turn the socket sfd into  connected fd
	connect_server(&sfd,&sin,len,serPort,serIp);

	show_menu(sfd);

	close(sfd);

	return 0;
}

全部功能函数

#include "dic.h"

//show the content of a string(an array of char) element by element
void show_buffer(char *buf){	
	for(int i = 0;i < sizeof(buf); i++){
		printf("%c",buf[i]);
	}
	printf(" at line %d.\n",__LINE__);
}

//to deal with dead child process
void zombie_deal(int signal){
	while(waitpid(-1,NULL,WNOHANG) > 0);
}

//convert struct tm to string
void time_to_string(char* buf){
	time_t t = time(NULL);
	struct tm *tm = localtime(&t);
	sprintf(buf,"%d-%02d-%02d %02d:%02d:%02d",tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);	
}

//the function is called by the server to tell the user if his request succeed or not
//every time when receiving a client request,such as register,log in,look up or view history
//for the attribute flag, normally 1 means success and 0 means fail.
void send_client_flag(int newfd,char* buf,int flag){

	bzero(buf,sizeof(buf));
	*(uint16_t*)buf = htons(flag);
	if(send(newfd,buf,sizeof(buf),0) < 0){
		ERR_MSG("Send flag");
		exit(0);
	}
	SUC_MSG("Send flag");

}

//to open the databse at the beginning phase
void sql_open(const char* path,sqlite3** db){
	if(sqlite3_open(path,db) < 0){
		ERR_MSG("Open database");
		exit(0);
	}
	SUC_MSG("Open database");
}

void sql_init_dictionary(sqlite3* db){

	char* errMsg = 0;
	int rc = 0;
	char sql[128] = "";

	//open the txt file which needs reading
	FILE *fp;
	char spell[128] = "";
	char meaning[128] = "";
	fp = fopen("dict.txt","r");
	if(fp == NULL){
		printf("Failed to open the txt file\n");
		exit(0);
	}
	SUC_MSG("dict.txt open");
	
	//store the max size of the txt file
	fseek(fp,0,SEEK_END);
	int totalByte = ftell(fp);
	fseek(fp,0,SEEK_SET);

	//while not reaching the end of the file,read every line and save the word
	//into the table
	while(1){
		//the first string before the space will be the spell of a word

		int j = 0;
		while(1){
			spell[j] = fgetc(fp);
			// when meeting a space,break to read the next word
			if(spell[j] == 32){
				spell[j] = 0;
				break;
			}else if(spell[j] == EOF){
				break;
			}
			j++;
		}

		int i = 0;
		//the second string(might containing space) will be the meaning of a
		//word
		while(1){
			meaning[i] = fgetc(fp);
			// when meeting a \n,break to read the next word
			if(meaning[i] == '\n'){
				meaning[i] = 0;
				break;
			}else if(meaning[i] == EOF){
				break;
			}
			if(meaning[i] != 32){
				i++;
			}
		}
		//if reaching the end of the file, break out of the loop
		if(meaning[i] == EOF){
			break;
		}

		//printf the current progress of reading && saving
		long cur = ftell(fp);
		float percentage = (cur / (float)totalByte) * 100;
		if(cur < totalByte){
			fprintf(stdout,"reading: %d%%\r",(int)percentage);
			fflush(stdout);
		}else{
			fprintf(stdout,"reading: %d%%\n",(int)percentage);
		}
		//clear sql statement
		bzero(sql,sizeof(sql));

		//insert the word into the table
		sprintf(sql,"insert into dictionary(spell, meaning) values(\"%s\",\"%s\");",spell,meaning);
		rc = sqlite3_exec(db,sql,NULL,NULL,&errMsg);
		if(rc != SQLITE_OK){
			printf("Error insert: %s at %d \n",sqlite3_errmsg(db),__LINE__);
			exit(0);
		}
		//clear both buffers
		bzero(spell,sizeof(spell));
		bzero(meaning,sizeof(meaning));
	}
	SUC_MSG("Record into table");
	sqlite3_free(errMsg);
}

void sql_init_tables(sqlite3 *db){
	char **pRes = NULL;
	int row = 0;
	int column = 0;
	char sql[256] = "";
	char* errMsg = 0;
	int rc = 0;

	// create the dictionary table if not exist
	strcpy(sql,"CREATE TABLE IF NOT EXISTS DICTIONARY(ID INTEGER PRIMARY KEY AUTOINCREMENT, SPELL CHAR, MEANING CHAR);");
	rc = sqlite3_exec(db,sql,NULL,NULL,&errMsg);
	if(rc != SQLITE_OK){
		printf("Error create table dictionary: %s at %d \n",sqlite3_errmsg(db), __LINE__);
		exit(0);
	}
	SUC_MSG("Create table DICTIONARY");	

	// create the user table if not exist
	strcpy(sql,"CREATE TABLE IF NOT EXISTS USER(ID INTEGER PRIMARY KEY AUTOINCREMENT, USERNAME CHAR, USERPASSWORD CHAR, FLAG INT);");
	rc = sqlite3_exec(db,sql,NULL,NULL,&errMsg);
	if(rc != SQLITE_OK){
		printf("Error create table user: %s at %d \n",sqlite3_errmsg(db), __LINE__);
		exit(0);
	}
	SUC_MSG("Create table USER");	

	// create the history table if not exist
	strcpy(sql,"CREATE TABLE IF NOT EXISTS HISTORY(ID INTEGER PRIMARY KEY AUTOINCREMENT, USERNAME CHAR,SPELL CHAR, MEANING CHAR, TIME DATETIME);");
	rc = sqlite3_exec(db,sql,NULL,NULL,&errMsg);
	if(rc != SQLITE_OK){
		printf("Error create table HISTORY: %s at %d \n",sqlite3_errmsg(db), __LINE__);
		exit(0);
	}
	SUC_MSG("Create table HISTORY");	

	//check if it's the first time server boots
	strcpy(sql,"SELECT * FROM DICTIONARY WHERE ID = 1;");
	rc = sqlite3_get_table(db,sql,&pRes,&row,&column,&errMsg);	
	if(rc != SQLITE_OK){
		printf("Error check if table empty: %s at %d \n",sqlite3_errmsg(db), __LINE__);
		exit(0);
	}
	if(row == 0){
		printf("This is the first time that server boots, start loading data from txt file\n");
		sql_init_dictionary(db);
	}
	sqlite3_free(errMsg);
}

//the function is called by the server to re-set a specific user's flag back to 1
//when a user log out,whether its normally or interupted,
void sql_flag_back(sqlite3* db, char* username){

	char sql[128] = "";
	char *errMsg;

	sprintf(sql,"UPDATE USER SET FLAG = 1 WHERE USERNAME = \"%s\";",username);
	int rc = sqlite3_exec(db,sql,NULL,NULL,&errMsg);
	if(rc != SQLITE_OK){
		printf("Error flag back touser table: %s at %d \n",sqlite3_errmsg(db), __LINE__);
		exit(0);
	}
	sqlite3_free(errMsg);
	SUC_MSG("User flag reset");	

}

//the function will be called after a user finished look up request.
void insert_history(sqlite3* db,char* username,char* word, char* meaning, char* curtime){

	char **pRes = NULL;
	int row = 0;
	int column = 0;
	char sql[128] = "";
	char* errMsg = 0;
	int rc = 0;

	//check if there is duplicated searching record of the specific user on the same word
	sprintf(sql,"SELECT * FROM HISTORY WHERE USERNAME = \"%s\" AND SPELL = \"%s\";",username,word);
	rc = sqlite3_get_table(db,sql,&pRes,&row,&column,&errMsg);	
	if(rc != SQLITE_OK){
		printf("Error search from history: %s at %d \n",sqlite3_errmsg(db), __LINE__);
		exit(0);
	}
	SUC_MSG("Search from history");	
	// if there isn't any record about this user searching on this word,insert
	// new record
	if(row == 0){
		sprintf(sql,"INSERT INTO HISTORY(USERNAME, SPELL, MEANING, TIME) VALUES(\"%s\", \"%s\", \"%s\", \"%s\");",username,word,meaning,curtime);
		int rc = sqlite3_exec(db,sql,NULL,NULL,&errMsg);
		if(rc != SQLITE_OK){
			printf("Error insert record into history: %s at %d \n",sqlite3_errmsg(db), __LINE__);
			exit(0);
		}
		SUC_MSG("Insert into history");	
	//if there has been already a record,update the time column, modify it with
	//the latest time.
	}else{
		sprintf(sql,"UPDATE HISTORY SET TIME = \"%s\" WHERE USERNAME = \"%s\" AND SPELL = \"%s\";",curtime,username,word);
		int rc = sqlite3_exec(db,sql,NULL,NULL,&errMsg);
		if(rc != SQLITE_OK){
			printf("Error update record into history: %s at %d \n",sqlite3_errmsg(db), __LINE__);
			exit(0);
		}
		SUC_MSG("Update history");	

	}
	sqlite3_free(errMsg);
	sqlite3_free_table(pRes);
}

//this function is called after receiving a request with an look up request
//operation code
void sql_look_up(int newfd, sqlite3* db,char* buf,char* username){

	int rc = 0;
	int row = 0;
	int column = 0;
	char **pRes = NULL;
	char *errMsg = NULL;
	char sql[128] = "";
	char word[128] = "";
	char curtime[32] = "";

	//extract the word from the buffer
	sprintf(word,"%s",buf+sizeof(short));
	strcpy(username,buf+ sizeof(short) + strlen(word)+1);
	printf("word = %s username = %s\n",word, username);

	sprintf(sql,"SELECT * FROM DICTIONARY WHERE SPELL = \"%s\";",word);	
	rc = sqlite3_get_table(db,sql,&pRes,&row,&column,&errMsg);	
	if(rc != SQLITE_OK){
		printf("Error check if user exists: %s at %d \n",sqlite3_errmsg(db), __LINE__);
		exit(0);
	}
	//if the word doesn't exist,send back a flag
	if(row == 0){
		send_client_flag(newfd,buf,0);
	}
	//if the word exist,send back a flag along with the meaning
	//save this search record to the database
	else{
		//send back to inform the user that the word is in the dictionary
		bzero(buf,sizeof(buf));
		*(short*)buf = htons(row);
		if(send(newfd,buf,sizeof(buf),0) < 0){
			ERR_MSG("Send back number of meaning");
		}
		SUC_MSG("Send back number of meaning");

		char meaning[128] = "";
		char buffer[256] = "";
		
		for(int i = column; i < (row + 1) * column; i++){
			if(i % column == column - 1){
				//send back the meaning and at the same time
				//prepare the meaning to save into history table
				bzero(buffer,sizeof(buffer));
				strcpy(buffer,pRes[i]);
				SUC_MSG(pRes[i]);
				buffer[strlen(pRes[i]) + 1] = '\0';
				SUC_MSG(buffer);
				if(send(newfd,buffer,sizeof(buffer),0) < 0){
					ERR_MSG("Send back meaning");
				}
				strcat(meaning,pRes[i]);	
			}
		}

		time_to_string(curtime);
		insert_history(db,username,word,meaning,curtime);
	}
	sqlite3_free(errMsg);
	sqlite3_free_table(pRes);

}

//the function is called by the server after receiving a view history request
//from the client
void sql_view_history(int newfd, sqlite3* db,char* username){

	int rc = 0;
	int row = 0;
	int column = 0;
	char **pRes = NULL;
	char *errMsg = NULL;
	char sql[128] = "";
	char buf[512] = "";

	sprintf(sql,"SELECT * FROM HISTORY WHERE USERNAME = \"%s\" ORDER BY TIME DESC;",username);	
	rc = sqlite3_get_table(db,sql,&pRes,&row,&column,&errMsg);	
	if(rc != SQLITE_OK){
		printf("Error check user history: %s at %d \n",sqlite3_errmsg(db), __LINE__);
		exit(0);
	}
	SUC_MSG("View history");

	//if there is no search record,send back a fail flag
	if(row == 0){

		send_client_flag(newfd,buf,0);
		
	}
	else{
		//send string by string from **pRes
		//send first how many strings there are to send
		*(short*)buf = htons(row * (column -2));
		*(short*)(buf+sizeof(short)) = htons(column);
		if(send(newfd,buf,sizeof(buf),0) < 0){
			ERR_MSG("Send record number");
		}
		SUC_MSG("Send record number");
		//send back every element of *qRes except the column id and the column 
		//username
		for(int i = column; i < (row + 1)*column;i++){
			if((i % column != 0) && (i % column != 1)){

				bzero(buf,sizeof(buf));
				strcpy(buf,pRes[i]);
				buf[strlen(pRes[i]) + 1] = '\0';
				if(send(newfd,buf,sizeof(buf),0) < 0){
					ERR_MSG("Send segments");
				}
				
			}
		}
	}
	sqlite3_free_table(pRes);
	sqlite3_free(errMsg);

}

int sql_if_user_exists(char* buf, char* username, char* userpassword,char* sql,sqlite3* db){

	int rc = 0;
	int row = 0;
	int column = 0;
	char **pRes = NULL;
	char *errMsg = NULL;

	sprintf(username,"%s",buf+sizeof(short));
	sprintf(userpassword,"%s",buf+sizeof(short)+strlen(username)+sizeof(char));
	sprintf(sql,"SELECT * FROM USER WHERE USERNAME = \"%s\";",username);	
	rc = sqlite3_get_table(db,sql,&pRes,&row,&column,&errMsg);	
	if(rc != SQLITE_OK){
		printf("Error check if user exists: %s at %d \n",sqlite3_errmsg(db), __LINE__);
		exit(0);
	}
	if(row == 0){
		sqlite3_free_table(pRes);
		sqlite3_free(errMsg);
		return 0;
	}
	else{
		sqlite3_free_table(pRes);
		sqlite3_free(errMsg);
		return 1;
	}
	sqlite3_free_table(pRes);
	sqlite3_free(errMsg);
	return 0;

}

void sql_register_user(char* sql, char* username,char* userpassword, sqlite3* db){	

	char *errMsg;

	sprintf(sql,"INSERT INTO USER(USERNAME, USERPASSWORD, FLAG) VALUES(\"%s\", \"%s\", 1);",username,userpassword);
	int rc = sqlite3_exec(db,sql,NULL,NULL,&errMsg);
	if(rc != SQLITE_OK){
		printf("Error insert into user table: %s at %d \n",sqlite3_errmsg(db), __LINE__);
		exit(0);
	}

	sqlite3_free(errMsg);
	SUC_MSG("One record inserted");	

}

int sql_login_user(int newfd, char* buf, char* username,char* userpassword,char* sql, sqlite3* db){

	int row = 0;
	int column = 0;
	char **pRes = NULL;
	char *errMsg = NULL;

	int rc = sql_if_user_exists(buf,username,userpassword,sql,db);
	//if a user doesn't exists send back a failure flag
	if(rc == 0){
		send_client_flag(newfd,buf,0);
	//if exist,check if the password matches
	}else{
		sprintf(username,"%s",buf+sizeof(short));
		sprintf(userpassword,"%s",buf+sizeof(short)+strlen(username)+sizeof(char));
		sprintf(sql,"SELECT * FROM USER WHERE USERNAME = \"%s\" AND USERPASSWORD = \"%s\" AND FLAG = 1;",username,userpassword);	
		rc = sqlite3_get_table(db,sql,&pRes,&row,&column,&errMsg);	
		if(rc != SQLITE_OK){
			printf("Error check if user exists: %s at %d \n",sqlite3_errmsg(db), __LINE__);
			exit(0);
		}
		//if doesn't match,send back a failure flag
		if(row == 0){
			send_client_flag(newfd,buf,0);
			sqlite3_free(errMsg);
			return 0;
		}
		//if do exist,send back a success flag as well as modify the user record
		//to re-set the flag column to 0
		else{
			send_client_flag(newfd,buf,1);
			sprintf(sql,"UPDATE USER SET FLAG = 0 WHERE USERNAME = \"%s\";",username);
			rc = sqlite3_exec(db,sql,NULL,NULL,&errMsg);
			if(rc != SQLITE_OK){
				printf("Error insert into user table: %s at %d \n",sqlite3_errmsg(db), __LINE__);
				exit(0);
			}
			SUC_MSG("User log in");
			sqlite3_free(errMsg);
			return 1;
		}	
	}
	sqlite3_free(errMsg);
	return 0;
}

//reset all the users' flag to 1 after rebooting the server
void sql_reset_all_flags(sqlite3* db){

	char *errMsg = 0;
	char sql[128] = "UPDATE USER SET FLAG = 1";

	int rc = sqlite3_exec(db,sql,NULL,NULL,&errMsg);
	if(rc != SQLITE_OK){
		printf("Error reset flags: %s at %d \n",sqlite3_errmsg(db), __LINE__);
		exit(0);
	}
	SUC_MSG("Reset all users' flag");

}

void create_socket(int *sfd){
	*sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd < 0){
		ERR_MSG("Create socket");
		exit(0);
	}
	SUC_MSG("Socket");
}

void bind_socket(int *sfd,struct sockaddr_in *sin, int *len, int port, const char* ip){
	sin->sin_family = AF_INET;
	sin->sin_port = htons(port);
	sin->sin_addr.s_addr = inet_addr(ip);
	if(bind(*sfd,(struct sockaddr*)sin,*len) < 0){
		ERR_MSG("Bind socket");
		exit(0);
	}
	SUC_MSG("Bind");
}
void quick_reuse(int *sfd){
	int reuse = 1;
	if(setsockopt(*sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) < 0){
		ERR_MSG("Reuse port");
	}
	SUC_MSG("Reuse port");
}
void listen_socket(int *sfd){
	if(listen(*sfd,128) < 0){
		ERR_MSG("Listen socket");
		exit(0);
	}
	SUC_MSG("Listen");
}

void connect_server(int *sfd,struct sockaddr_in *sin, socklen_t addrlen,int port, const char* ip){
	sin->sin_family = AF_INET;
	sin->sin_port = htons(port);
	sin->sin_addr.s_addr = inet_addr(ip);

	if(connect(*sfd,(struct sockaddr*)sin,addrlen) < 0){
		ERR_MSG("Connect server");
		exit(0);
	}
	SUC_MSG("Connected to server");
}

int accept_socket(int sfd,struct sockaddr_in *addr, socklen_t *addrlen){
	int newfd;
	newfd = accept(sfd,(struct sockaddr*)addr,addrlen);
	if(newfd < 0){
		ERR_MSG("Accept socket");
		return -1;
	}
	printf("[%s:%d] has successfully connected at line %d\n",inet_ntoa(addr->sin_addr),ntohs(addr->sin_port),__LINE__);
	return newfd;
}

void deal_dictionary(int newfd,struct sockaddr_in cin,sqlite3* db,char* username){

	char buf[256] = "";

	//look up or view history
	while(1){
		bzero(buf,sizeof(buf));
		int res = recv(newfd,buf,sizeof(buf),0);
		if(res <= 0){
			//update the user table and change the flag to 1
			printf("[%s:%d] has been off at line %d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),__LINE__);
			if(close(newfd) < 0){
				ERR_MSG("Close");
			}
			sql_flag_back(db, username);
			exit(0);
		}
		SUC_MSG("Request from user");
		if(ntohs(*(short*)buf) == 3){
			sql_look_up(newfd,db,buf,username);
			
		}else if(ntohs(*(short*)buf) == 4){

			sql_view_history(newfd,db,username);

		}else if(ntohs(*(short*)buf) == 5){
			sql_flag_back(db, username);
			printf("[%s:%d] has logged out at line %d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),__LINE__);
			break;
		}
	}
}
void deal_client(int newfd,struct sockaddr_in cin,sqlite3* db){
	//operation code(client to server):
	//the first 2 bytes of string will be the operation code
	//1.register strlen(username) + 0 1byte + strlen(userpassword) + 0 1byte
	//2.login + strlen(username) +0 1byte + strlen(userpassword) + 0 1byte
	//3.look up strlen(spell) + 0 1byte
	//4.view history
	//5.quit second menu
	
	//operation code(server to client):
	//1 means success
	//0 means failure
	//>1 means in view history means number of records

	//log in or register
	char buf[256] = "";
	char sql[128] = "";	
	char username[16] = "";
	char userpassword[16] = "";

	while(1){
		bzero(buf,sizeof(buf));
		int res = recv(newfd,buf,sizeof(buf),0);
		SUC_MSG("Receive from cli");

		if(res <= 0){
			//user quit without log in
			
			printf("[%s:%d] has been off at line %d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),__LINE__);
			if(close(newfd) < 0){
				ERR_MSG("Close");
			}
			exit(0);
		}
		if(ntohs(*(short*)buf) == 1){
			//if successfully registered
			//insert its name and password into the user table

			int rc = sql_if_user_exists(buf,username,userpassword,sql,db);
			if(rc == 0){
				sql_register_user(sql,username,userpassword,db);
				send_client_flag(newfd,buf,1);
			}else{
				send_client_flag(newfd,buf,0);
			}
		
		}else if(ntohs(*(short*)buf) == 2){
			//if successfully log in
			//update the user table and alter the flag to 0
			if(sql_login_user(newfd,buf,username,userpassword,sql,db) == 1){
				deal_dictionary(newfd,cin,db,username);
			}
		}
	}
}
//called by the client if require looking up
void look_up(int sfd, char* username){

	char word[32] = "";
	char buf[256] = "";
	char meaning[64] = "";
	
	printf("please enter a word>>>");
	fgets(word,sizeof(word),stdin);
	word[strlen(word) - 1] = 0;

	//Loop in case there are bad tcp requests
	while(1){
		bzero(buf,sizeof(buf));
		sprintf(buf,"%c%c%s%c%s%c",0,3,word,'\0',username,'\0');
		//send a look up request to the server
		if(send(sfd,buf,sizeof(buf),0) < 0){
			ERR_MSG("Send to server");
		}
		SUC_MSG("Send to server");

		//receive the request result
		bzero(buf,sizeof(buf));
		ssize_t res = 0;
		if((res=recv(sfd,buf,sizeof(buf),0)) < 0){
			ERR_MSG("Look up");
		}
		printf("res=%ld __%d__\n", res, __LINE__);
		SUC_MSG("Look up");
		//if the word exists in the dictionary
		if(ntohs(*(short*)buf) >= 1){
			SUC_MSG("The word found");
			int num = ntohs(*(short*)buf);
			for(int i = 0; i < num;i++){
				bzero(buf,sizeof(buf));
				if(recv(sfd,buf,sizeof(buf),0) < 0){
					ERR_MSG("Look up");
				}	
				SUC_MSG(buf);
				strcat(meaning,buf);
				if(strcmp(meaning,"") == 0){
					fflush(stdout);
				}
			}
			if(strcmp(meaning,"") != 0){
				printf("The word means %s,\n",meaning);
				break;
			}
		}else{
			printf("The word isn't included in the dictionary.\n");
			break;
		}
	}
}

//called by the client if require viewing history
void view_history(int sfd,char* username){

	char buf[512] = "";

	sprintf(buf,"%c%c%s%c",0,4,username,'\0');	

	//send a view request to the server
	if(send(sfd,buf,sizeof(buf),0) < 0){
		ERR_MSG("Send to server");
	}
	SUC_MSG("Send to server");

	//receive the request result
	bzero(buf,sizeof(buf));
	if(recv(sfd,buf,sizeof(buf),0) < 0){
		ERR_MSG("View history");
	}
	SUC_MSG("View history");
	if(ntohs(*(short*)buf) == 0){
		printf("No record of user %s.\n",username);
		return;
	}
	else{
		//print out every string from the server
		//print out \n every 3 strings 
		int num = ntohs(*(short*)buf);
		int column = ntohs(*(short*)(buf + sizeof(short)));
		for(int i = 0; i < num; i++){

			bzero(buf,sizeof(buf));
			if(recv(sfd,buf,sizeof(buf),0) < 0){
				ERR_MSG("View history");
			}
			
			printf("%-15s ",buf);
			
			if((i % (column - 2)) == (column - 3)){
				puts("");
			}
		}
	}
	puts("");
}

void log_out(int sfd){

	char buf[2];
	*(uint16_t *)buf = htons(5);
	if(send(sfd,buf,sizeof(buf),0) < 0){
		ERR_MSG("Send log out");
	}
	SUC_MSG("Log out");
}

void show_second_menu(int sfd, char* username){
	char buf[256]="";
	ssize_t res = 0;
//	if((res=recv(sfd,buf,sizeof(buf),0)) < 0){
//		ERR_MSG("Look up");
//	}
	printf("res=%ld __%d__\n", res, __LINE__);



	char c;
	while(1){	
		printf("_________Welcome________\n");
		printf("         %s\n",username);
		printf("------------------------\n");
		printf("|     1.look up        |\n");
		printf("|     2.view history   |\n");
		printf("|     3.exit           |\n");
		printf("------------------------\n");
		c = getchar();
		system("clear");
		while(getchar()!= 10);
		if( c == '1'){
			look_up(sfd,username);
		}else if(c == '2'){
			view_history(sfd,username);
		}else if(c == '3'){
			log_out(sfd);
			break;
		}else{
			printf("Not a valid option,please re-enter\n");
		}
	}
}

void cli_register(int sfd){

	char username[16] = "";
	char password[16] = "";
	//operation code 2bytes + username + \0 + password + \0
	char buf[36] = "";

	printf("|       1.register     |\n");	
	printf("username>>>");
	fgets(username,sizeof(username),stdin);
	username[strlen(username) - 1] = 0;

	printf("password>>>");
	fgets(password,sizeof(password),stdin);
	password[strlen(password) - 1] = 0;

	sprintf(buf,"%c%c%s%c%s%c",0,1,username,'\0',password,'\0');

	//send the register info to the server
	if(send(sfd,buf,sizeof(buf),0) < 0){
		ERR_MSG("Send to server");
	}
	SUC_MSG("Send to server");

	//collect the success flag from the server
	bzero(buf,sizeof(buf));
	if(recv(sfd,buf,sizeof(buf),0) < 0){
		ERR_MSG("Receive from server");
	}
	SUC_MSG("Flag received");
	if(ntohs(*(short*)buf) == 1){
		printf("User %s is successfully registered.\n",username);
	}else{
		printf("User %s has already been registered.\n",username);
	}
}

void cli_log_in(int sfd){	

	char username[16] = "";
	char password[16] = "";
	//operation code 2bytes + strlen(username) + \0 + strlen(password) + \0
	char buf[36] = "";

	printf("|       2.log in       |\n");
	printf("username>>>");
	fgets(username,sizeof(username),stdin);
	username[strlen(username) - 1] = 0;

	printf("password>>>");
	fgets(password,sizeof(password),stdin);
	password[strlen(password) - 1] = 0;

	sprintf(buf,"%c%c%s%c%s%c",0,2,username,'\0',password,'\0');

	//send the register info to the server
	if(send(sfd,buf,sizeof(buf),0) < 0){
		ERR_MSG("Send to server");
	}
	SUC_MSG("Send to server");

	//collect the success flag from the server
	bzero(buf,sizeof(buf));
	if(recv(sfd,buf,sizeof(buf),0) < 0){
		ERR_MSG("Receive from server");
	}
	SUC_MSG("Flag received");
	if(ntohs(*(short*)buf) == 1){
		printf("User %s has successfully logged in.\n",username);
		show_second_menu(sfd,username);
	}else{
		printf("User %s log in failed.\n",username);
	}
}

void show_first_menu(int sfd){
	char c;
	while(1){	
		printf("_______E-dictionary_____\n");
		printf("------------------------\n");
		printf("|       1.register     |\n");
		printf("|       2.log in       |\n");
		printf("|       3.exit         |\n");
		printf("------------------------\n");
		c = getchar();
		system("clear");
		while(getchar()!= 10);
		if( c == '1'){
			cli_register(sfd);
		}else if(c == '2'){
			cli_log_in(sfd);
		}else if(c == '3'){
			break;
		}else{
			printf("Not a valid option,please re-enter\n");
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值