⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myftpserver.c

📁 实现LINUX下的一个简单FTP协议。用PASSWORD.c来维护一个用户表
💻 C
📖 第 1 页 / 共 2 页
字号:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<errno.h>
#include<string.h>
#include<pthread.h>
#include<dirent.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>

#define BACKLOG 5
#define ASSCI 0
#define BIN 1
#define SPEED 512
#define SUC_FLAG "USER Certification Successed!"
#define FAIL_FLAG "USER Certification Failed!"
#define data_len 1024;
#define cmd_len 50;
#define mput_limit 10;
#define mget_limit 10;


//请更新用户/密码表的路径
//********************************************************
#define PASSWORD "/home/young/桌面/ftp/ftpserver/password.c"
//********************************************************



int pswd_fd;
FILE *ps_file;

void lpwd(int dataSocketFd);
void lmkdir(int dataSocketFd,char *dirName);
void lrmdir(int dataSocketFd,char *dirName);
void ldir(int dataSocketFd);
void lcd(int dataSocketFd,char *dirName);
int getUpDir(char *currentDirPath) ;//获得当前目录的上一级目录
struct sockaddr_in make_localaddr(short int ,long int);
int init_server(short int ,long int);
int checkclient(int,int);
int download_server2client(int clientfd,char *filename,int download_type);
int put_client2server(int clientfd,char *filename,int type);
void client_op(int,int);
void server_op(void *arg);

//****
struct clientinfo{ // 登录信息
	char name[10];
	char passwd[6];
};
struct arg_info {
	int arg_mount;
	char *arg_array[512];	
};

struct positv_client{// 记录当前活动用户名
	char name[20];
        struct positv_client *next;
};

struct fd_struct {  // 套接字
	int client_fd;
	int data_fd;
};

struct usr_info {  // 用户信息
	char usrname[20];
	char psword[20];
};
// 用户文件中的所有人员信息
struct usr_info ALL_USERS[512] = {
	{"abcc","ddd"}		
};
// 当前活动人员信息
struct usr_info POSITIVE_USERS[512] = {
};
//****



// 全局变量

char comstr[100];
char testlink[12];
int infosockfd,datasockfd,op_clientfd,all_cltnum,positv_cltnum,_current;
int count_all;
char help[]="\t**************************************\n\t*count current --显示当前活动用户数*\n\t*count all --显示系统访客总数      *\n\t*list--显示当前在线用户列表        *\n\t*quit--退出服务器                  *\n\t**************************************\n";;
pthread_mutex_t mutex;
pthread_t client_pthread[BACKLOG]; // 最大线程数 



int main(int argc,char *argv[]){	//argv[1]为端口号argv[2]为IP 
	
	init_envi();

	// 创建客户会话线程
	struct arg_info arg_inf={
		0,{""}	
	};
	pthread_t server_pd;
	arg_inf.arg_mount = argc;
	int i = 0;
	char main_cmd[128] = {""};

	for (; i< argc; i++) {
		//memset(arg_inf.arg_array[i],'\0',sizeof(arg_inf.arg_array[i]));
		arg_inf.arg_array[i]=argv[i];
	}
	pthread_create(&server_pd,0,(void *)&main_operation,(void *)&arg_inf);//客户线程创建
	pthread_detach(server_pd);//分离的
	
	printf("\t\tmyftp server\n");
	printf("%s",help);
	printf("myserver>");
	fgets(main_cmd,sizeof(main_cmd),stdin);
	while (strcmp(main_cmd,"quit\n")) {
		if(!strcmp(main_cmd,"count current\n"))
			printf("当前活动用户数 :%d\n",_current);
		if(!strcmp(main_cmd,"count all\n"))
			printf("系统访客总数 :%d\n",count_all);
		if (!strcmp(main_cmd,"list\n")) {
			printf("当前活动用户 :\n");
			int k = 0;
			for (;k<_current; k++ ) {
				printf("第%d号用户:%s\n",k+1,POSITIVE_USERS[k].usrname);			
			}			
		}
		else
			printf("请输入正确指令!\n");
		printf("myserver>");
		fgets(main_cmd,sizeof(main_cmd),stdin);




		
	}
}








int main_operation(void *arg) {
	sleep(1);
	struct arg_info *arg_inf;
	arg_inf = (struct arg_info *)arg;
	pthread_mutex_init(&mutex,NULL);
	int i=0;
	

	
	if((*arg_inf).arg_mount == 1 || (*arg_inf).arg_mount >3){	// 输入错误
		perror("start failed.\n");
		return -1;
	}else if((*arg_inf).arg_mount == 2){	// 只输入端口	
				short int *port;
				port = (short int *)((*arg_inf).arg_array[1]);
				infosockfd = init_server(*port,0);

				short int dataport;
				dataport = *port + 1;
				datasockfd = init_server(dataport,0);
				

				if(infosockfd == -1){
					perror("server init failed.\n");
					return -1; 
				}  else if(infosockfd != -1){

					op_clientfd = checkclient(infosockfd,datasockfd);

					
					return 0;
				}
		} else if((*arg_inf).arg_mount == 3){	
				short int *port;
				long int ip;
				port = (short int *) ((*arg_inf).arg_array[1]);
				ip = inet_addr(((*arg_inf).arg_array[2]));	//把字符串转换为IP格式
				infosockfd = init_server(*port,ip);
				short int dataport;
				dataport = *port + 1;
				datasockfd = init_server(dataport,ip);
				
				if(infosockfd == -1){
						perror("server init failed.\n");
						return -1; 
					}  else if(infosockfd != -1){
						op_clientfd = checkclient(infosockfd,datasockfd);
						return 0;
					}
	 
		 }
	
}



int init_envi(){

	int pswd_lenth = 0;
	ps_file = fopen(PASSWORD,"rb");

	lseek(pswd_fd,0,SEEK_SET);// //置读写指针到文件头
	pswd_fd = fileno(ps_file);
	pswd_lenth = lseek(pswd_fd,0,SEEK_END);//获取文件长度
	lseek(pswd_fd,0,SEEK_SET);

	int i=0;int j=0; // j=0 当前读到的是名字,j=1 当前读到的是密码
	int _ui,_pi; _ui=0; _pi=0;
	char ch[512]="a";
	char par[512]="";char _usrname[512]=""; char _psword[512]="";


	while (i<pswd_lenth) {
		read(pswd_fd,ch,1);

		if (!strcmp(ch,",")) { // 读名字结束
			_ui = 0;
			j = 1;
		} else if (!strcmp(ch, ";")) { // 读密码结束
			_pi = 0;
			j = 0;



			strcpy(ALL_USERS[all_cltnum].usrname,_usrname);
			strcpy(ALL_USERS[all_cltnum].psword,_psword);
			memset(_usrname,'\0',sizeof(_usrname));
			memset(_psword,'\0',sizeof(_psword));
			all_cltnum++;

		} else {

			if ( j == 0) {
				_usrname[_ui++] = ch[0];
			} else {
				_psword[_pi++] = ch[0];
			}
		}
		i++;
	}//while_end
	
	//memset(ALL_USERS[all_cltnum++].usrname,'\0',sizeof(ALL_USERS[all_cltnum].usrname));
	//memset(ALL_USERS[all_cltnum++].psword,'\0',sizeof(ALL_USERS[all_cltnum].psword));
		
	strcpy(ALL_USERS[all_cltnum].usrname,_usrname);
	strcpy(ALL_USERS[all_cltnum].psword,_psword);
	ALL_USERS[all_cltnum].psword[strlen(ALL_USERS[all_cltnum].psword)-1] = '\0';
	all_cltnum++;


}	


	


int init_server(short int port,long int ip){
	int _sockfd;
	struct sockaddr_in localaddr;
	_sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(_sockfd == -1 ){
		printf("\nsock creat error.\n");
		return -1;
	}
	localaddr = make_localaddr(port,ip);//设置本地地址和端口	

	if(bind(_sockfd,(struct sockaddr *)&localaddr,sizeof(localaddr)) == -1){//绑定地址及端口
		printf("\nbind() error.\n");
		return -1;
	}
	
	if((listen(_sockfd,BACKLOG)) == -1){//最大等待5个客户
		printf("\nlisten() error.\n");
		return -1;
	}
	
	return _sockfd;
	
}




void client_op(int clientfd,int datafd){//服务函数
struct fd_struct fd_st={0,0};
fd_st.client_fd = clientfd;
fd_st.data_fd = datafd;
	//pthread_mutex_lock(&mutex);

	pthread_create(&client_pthread[positv_cltnum],0,(void *)&server_op,(void *)&fd_st);//客户线程创建
	//pthread_detach(client_pthread[positv_cltnum]);//分离的

	//pthread_mutex_unlock(&mutex);
	}


//设置IP和端口
struct sockaddr_in make_localaddr(short int port,long int ip){
	struct sockaddr_in localaddr;
	memset(localaddr.sin_zero,'\0',sizeof(localaddr.sin_zero));
	localaddr.sin_family = AF_INET;  
	localaddr.sin_port =port;
	if(ip == 0){
	
	localaddr.sin_addr.s_addr = INADDR_ANY;//未输入IP,用默认
	}
	else if(ip != 0){
	localaddr.sin_addr.s_addr = ip;//转为网络字节顺序	
}
      
	
	return localaddr;
}



void server_op(void *arg){//服务函数
struct fd_struct *fd_st;
fd_st = (struct fd_struct *)arg;

	int cmd_arg_mount=0;      // 记录命令参数个数
	char dealmessage[200]=""; // 存储处理结果
	char *cmd_arg_array[512]={""}; // 存放命令及参数
	

	char currentDirPath[200] = ""; // 存放当前路径
	int i = 0;

	int _clientfd = 0;
	int _datasockfd = 0;
	
	int dataclient_addrlen;
	struct sockaddr_in dataclient_addr;

	dataclient_addrlen = sizeof(dataclient_addr);
	
	
	
	_clientfd = (*fd_st).client_fd;
	_datasockfd = (*fd_st).data_fd;

int datafd;
datafd = accept(_datasockfd,(struct sockaddr *)&dataclient_addr,&dataclient_addrlen);

	

int flag = 1;int flag2=1;	


// 用户验证
char client_msg[512]="";
read(_clientfd,client_msg,512);

int iii = 0;
if (!(iii=checkpassword(client_msg))) { // 没有通过验证
	write(datafd,FAIL_FLAG,512);
	// 错误处理.
	close(datafd);
	pthread_exit(0);
} 

write(datafd,SUC_FLAG,512);
_current++;count_all++;

// 读操作
while(flag){	
		flag2= 0;
		int __current,_all_cltnum ;
		__current = _current;
		_all_cltnum = all_cltnum;
		memset(comstr,'\0',sizeof(comstr));



		read(_clientfd,comstr,512);
// 为什么read后_current会被冲掉?
		_current = __current;
		all_cltnum = _all_cltnum;

	if (!strcmp(comstr,"quit")){ 
		flag=0;
		_current--;
	}

	// 解析命令
	cmd_arg_mount=get_argc_argv(comstr,cmd_arg_array);

	// 处理命令
	if (cmd_arg_mount) {
		if (!strcmp(cmd_arg_array[0],"lmkdir")) {
			int i;flag2 =1;
			//printf("get command lmkdir!\n");
			if(cmd_arg_mount > 2){
				for(i = 1;i < cmd_arg_mount;i++)
					lmkdir(datafd,cmd_arg_array[i]);
			}
			if(cmd_arg_mount == 2)
				lmkdir(datafd,cmd_arg_array[1]);
			if(cmd_arg_mount == 1){
				write(datafd,"need filename..",15);

			}
			//printf("lmkdir done!\n");
		}

		if (!strcmp(cmd_arg_array[0],"lrmdir")) {
			int i;flag2 =1;
			//printf("get command lrmdir!\n");
			if(cmd_arg_mount > 2){
				for(i = 1;i < cmd_arg_mount;i++)
					lrmdir(datafd,cmd_arg_array[i]);
			}
			if(cmd_arg_mount == 2)
				lrmdir(datafd,cmd_arg_array[1]);
			if(cmd_arg_mount == 1)
				write(datafd,"need filename..",15);
			//printf("lrmdir done!\n");
			
		}
		if (!strcmp(cmd_arg_array[0],"lpwd")) {
			//printf("get command lpwd!\n");
			flag2 =1;
			if(cmd_arg_mount > 1)
				write(datafd,"type error!",11);
			else
				lpwd(datafd);
			//printf("lpwd done!");
		}
		if (!strcmp(cmd_arg_array[0],"lcd")) {
			///printf("get command lcd!\n");
			flag2 =1;
			if(cmd_arg_mount == 2)
				lcd(datafd,cmd_arg_array[1]);
			else 
				write(datafd,"type error!",11);
			//printf("lcd done!\n");
		}
		if (!strcmp(cmd_arg_array[0],"ls")) {
			//printf("get command ls\n");
			flag2 =1;
				
			if(cmd_arg_mount == 1)
				ldir(datafd);
			else
				write(datafd,"typeflag =0; error!",11);
			///printf("ls done!\n");
		}
		// put 
		if(!strcmp(cmd_arg_array[0],"put")){
				//printf("get command put\n");
				flag2 =1;
				if(cmd_arg_mount == 2){
					put_client2server(datafd,cmd_arg_array[1],0);
					write(datafd,"get over!",9);
				}
				if(cmd_arg_mount ==3){
					if(!strcmp(cmd_arg_array[2],"assci")||!strcmp(cmd_arg_array[2],"ASSCI") ){
						put_client2server(datafd,cmd_arg_array[1],0);
						write(datafd,"get over!",9);
					}
					else if(!strcmp(cmd_arg_array[2],"bin")||!strcmp(cmd_arg_array[2],"BIN") ){
						put_client2server(datafd,cmd_arg_array[1],1);
						write(datafd,"get over!",9);
					}
				}
				else	write(datafd,"enter error!",12);	
		}
		// get
		if(!strcmp(cmd_arg_array[0],"get")){
				//printf("get command put\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -