网盘报告。

本文介绍了使用hujing和zjy账号在网盘server.c和client.c中的操作,包括注册、登录、文件上传与下载的密码保护机制。重点展示了用户hujing如何上传文件及他人下载文件时的权限验证流程。
摘要由CSDN通过智能技术生成

注册两个账号,用户名和密码分别为hujing、hello和zjy、123;

登陆hujing账号,上传一个路径为/home/hujing/Desktop/homework/long的文件,可以看到网盘的文件夹中下载到了一个命名为hujing_file的文件,且该文件头四个字节为该文件的密码;

当用户下载自己上传的文件时,不需要输入密码;这里为用户hujing下载自己上传的文件file,下载的文件命名为xixi

当用户下载别的用户上传的文件时,需要输入密码;这里为用户zjy登陆下载用户hujing上传的文件file,下载的文件命名为haha,此时需要输入密码3728,可以看到下载成功;

网盘server.c

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

unsigned short port = 8990;	// 本地端口
int sockfd=0;
int connfd=0;
//char id[50];

void setserver()
{
	//创建套接字
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0)
	{
		perror("socket");
		exit(-1);
	}
	//设置本地地址结构体
	struct sockaddr_in my_addr;
	bzero(&my_addr, sizeof(my_addr));			// 清空,保证最后8字节为0
	my_addr.sin_family = AF_INET;				// ipv4
	my_addr.sin_port   = htons(port);			// 端口
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY);// ip,INADDR_ANY为通配地址其值为0
	//将本地ip、端口与套接字socket相关联起来
	int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));
	if( err_log == -1)
	{
		perror("binding");
		close(sockfd);
		exit(-1);
	}
	//监听,监听套接字改为被动,创建连接队列
	err_log = listen(sockfd, 10);
	if(err_log == -1)
	{
		perror("listen");
		close(sockfd);
		exit(-1);
	}
	printf("server at port=%d...\n",port);
}

void hjregister()
{
	char send_buf[1024];
	char recv_buf[1024];
	char id[50];
	char password[100];
	//printf("connfd=%d\n",*connfd);
	//读取注册信息并存入文件
	recv(connfd,id,sizeof(id),0);
	recv(connfd,password,sizeof(password),0);
	int fd=open("/home/hujing/hj/fileuseridinf",O_WRONLY|O_APPEND);//将name和写入文件
	sprintf(send_buf,"%s\t%s\n",id,password);
	write(fd,send_buf,strlen(send_buf));
	printf("已存入文件 %s %s\n",id,password);
	bzero(send_buf,strlen(send_buf));
	close(fd);
}

void upload(char id[50])
{
	//recv用户发过来的文件路径 打开该文件并 读取
	char filepath[100];
	recv(connfd,filepath,sizeof(filepath),0);
	//recv网盘中文件名
	char filename[50];
	recv(connfd,filename,sizeof(filename),0);
	//密码
	char password[20];
	recv(connfd,password,sizeof(password),0);
	//在服务器所在文件夹创建一个新的文件 命名为
	char newpath[150];
	sprintf(newpath,"/home/hujing/hj/file/%s_%s",id,filename);	
	//open用户路径和网盘中文件路径
	int ofd=open(filepath,O_RDONLY);
	if(ofd<0) 
	{
		send(connfd,"PATH ERROR",strlen("PATH ERROR"),0);
		printf("PATH ERROR\n");
		close(ofd);
		return;
	}
	int ifd=open(newpath,O_CREAT|O_WRONLY,0777);
	//一次read1024个字节并记录
	int readsize=1024;
	int writesize=0;
	int cnt=0;
	writesize=write(ifd,password,4);
	while(readsize==1024)
	{
		char temp[1024];
		readsize=read(ofd,temp,sizeof(temp));
		//printf("%d readsize=%d\n",cnt+1,readsize);
		writesize=write(ifd,temp,readsize);
		cnt++;
	}	
	char send_buf[1024];
	bzero(send_buf,sizeof(send_buf));
	sprintf(send_buf,"SUCCESS 共读取到%d个字节",1024*(cnt-1)+readsize);
	send(connfd,send_buf,strlen(send_buf),0);
	close(ifd);
	close(ofd);
}

void download(char id[50])
{
	//printf("download\n");
	int flag=1;
	char owner[50];
	recv(connfd,owner,sizeof(owner),0);
	char filename[50];
	recv(connfd,filename,sizeof(filename),0);
	char newpath[100];
	recv(connfd,newpath,sizeof(newpath),0);
	char password[50];
	if(strcmp(owner,id)!=0)
	{
		recv(connfd,password,sizeof(password),0);
		flag=0;
	}
	char filepath[150];
	bzero(filepath,sizeof(filepath));
	sprintf(filepath,"/home/hujing/hj/file/%s_%s",owner,filename);
	int ofd=open(filepath,O_RDONLY);
	//recv stor filepath
	int readsize=1024;
	int writesize=0;
	int cnt=0;
	if(ofd<0) 
	{
		send(connfd,"nameerror",strlen("nameerror"),0);
		//printf("NAME ERROR\n");
		perror("file open");
		close(ofd);
		return;
	}
	else
	{
		int ifd=open(newpath,O_CREAT|O_WRONLY,0777);
		send(connfd,"namecorrect",strlen("namecorrect"),0);
		char truepass[20];
		read(ofd,truepass,4);
		if(strcmp(owner,id)!=0)
		{
			if(strcmp(password,truepass)==0)
				flag=1;
			else send(connfd,"passworderror",strlen("passworderror"),0);
		}
		if(flag)
			while(readsize==1024)
			{
				char temp[1024];
				readsize=read(ofd,temp,sizeof(temp));
				//printf("%d readsize=%d\n",cnt+1,readsize);
				writesize=write(ifd,temp,readsize);
				cnt++;
			}
		close(ifd);
	}
	char send_buf[1024];
	bzero(send_buf,sizeof(send_buf));
	sprintf(send_buf,"SUCCESS 共下载到%d个字节",1024*(cnt-1)+readsize);
	printf("%s共下载%d个字节\n",id,1024*(cnt-1)+readsize);
	send(connfd,send_buf,strlen(send_buf),0);
	close(ofd);
}

void checkdir()
{
	printf("checkdir\n");
	char send_buf[1024];
	char temp[1024];
	bzero(temp,sizeof(temp));
	bzero(send_buf,sizeof(send_buf));
	DIR *dir;
	struct dirent *entry;
	dir=opendir("/home/hujing/hj/file");
	while((entry=readdir(dir))!=NULL)
	{
		if(strcmp(entry->d_name,".")==0 || strcmp(entry->d_name,"..")==0)
			continue;
		else 
		{
			//printf("%s\t",entry->d_name);
			strcpy(temp,send_buf);
			sprintf(send_buf,"%s %s",entry->d_name,temp);
		}
	}
	send(connfd,send_buf,strlen(send_buf),0);
	closedir(dir);
}

void hjlogin()
{
	char recv_buf[1024];
	char send_buf[1024];
	char id[50];
	char searchid[50];
	bzero(searchid,sizeof(searchid));
	recv(connfd,searchid,sizeof(searchid),0);
	char searchpass[100];
	bzero(searchpass,sizeof(searchpass));
	recv(connfd,searchpass,sizeof(searchpass),0);
	int fd=open("/home/hujing/hj/fileuseridinf",O_RDONLY);
	bzero(send_buf,sizeof(send_buf));
	read(fd,send_buf,sizeof(send_buf));
	close(fd);
	int i=0;
	int j=0;
	char temp[150];//存储一条信息
	int flag=0;//判断密码是否输入正确
	char success[20]="LOGINSUCCESS";
	for(int i=0;i<(int)strlen(send_buf);i++)
	{
		if(send_buf[i]-'\n'!=0) temp[j]=send_buf[i];
		else
		{
			char tempid[50];
			char temppass[100];
			sscanf(temp,"%s\t%s",tempid,temppass);
			if(strcmp(tempid,searchid)==0&&strcmp(searchpass,temppass)==0)
			{
				send(connfd,success,strlen(success),0);
				printf("\t%s LOG IN\n",tempid);
				flag=1;
				strcpy(id,tempid);
				break;
			}
			j=-1;
			bzero(temp,strlen(temp));
		}
		j++;
	}
	if(flag)
	{
		int flag1=0;
		while(1)
		{
			//recv
			bzero(recv_buf,strlen(recv_buf));
			recv(connfd,recv_buf,sizeof(recv_buf),0);
			//菜单 上传/下载/查看目录
			char select=recv_buf[1];
			switch(select)
			{
				case '1':upload(id);break;//上传
				case '2':download(id);break;//下载
				case '3':checkdir();break;//查看目录
				case '4':flag1=1;break;//退出
			}
			if(flag1) break;
		}
		
	}
	else	send(connfd,"failure",strlen("failure"),0);
}

void run()
{
	pthread_detach(pthread_self());
	char recv_buf[1024];
	int flag=0;
	while(1)
	{
		bzero(recv_buf,strlen(recv_buf));
		recv(connfd,recv_buf,sizeof(recv_buf),0);
		char select=recv_buf[1];
		switch(select)
		{
			case '1':hjregister();break;//注册
			case '2':hjlogin();break;//登陆
			case '3':flag=1;break;//退出
		}
		if(flag) break;
	}
}

int main()
{
	setserver();
	struct sockaddr_in client_addr;
	char cli_ip[INET_ADDRSTRLEN] = "";	   //INET...是ipv4的长度
	socklen_t cliaddr_len = sizeof(client_addr);    //socklen_t 一种数据类型 accept函数中第三个参数的长度必须和int相同  32和64位 下的socklen_t和int长度不同
	while(1)
	{
		umask(0000);
		int fd=open("/home/hujing/hj/fileuseridinf",O_CREAT,0777);//存储id
		connfd = accept(sockfd, (struct sockaddr*)&client_addr, &cliaddr_len);
		if(connfd<0)
		{
			perror("accept");
			continue;
		}
		inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);
		printf("\nclient ip=%s,port=%d,connfd=%d\n", cli_ip,ntohs(client_addr.sin_port),connfd);
		pthread_t pth;
		pthread_create(&pth,NULL,run,&connfd);
	}
	return 0;
}

网盘client.c

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

unsigned short port = 8990;        		// 服务器的端口号
char *server_ip = "127.0.0.1";    	// 服务器ip地址
int sockfd;
char id[50];
char send_buf[512];
char recv_buf[512];

void setclient()
{
        sockfd = socket(AF_INET, SOCK_STREAM, 0);// 创建套接字
        if(sockfd < 0)
        {
                perror("socket");
                exit(-1);
        }
        // 设置服务器地址结构体
        struct sockaddr_in server_addr;
        bzero(&server_addr,sizeof(server_addr)); // 初始化服务器地址
        server_addr.sin_family = AF_INET;       // IPv4
        server_addr.sin_port = htons(port);     // 端口
        inet_pton(AF_INET, server_ip, &server_addr.sin_addr.s_addr);    // 转换ip地址格式
	// 主动连接服务器
	int err_log = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
	if(err_log != 0)
	{
		perror("connect");
		exit(-1);
	}
}

void hjregister()
{
	//注册
	printf(">>>input your name:");
	scanf("%s",id);
	send(sockfd,id,strlen(id),0);
	printf("\n>>>input your password:");
	scanf("%s",send_buf);
	send(sockfd,send_buf,strlen(send_buf),0);
	bzero(send_buf,sizeof(send_buf));
}

void upload()
{
	//printf("upload\n");
	//send服务器filepath & filename
	printf(">>>input upload filepath:");
	char filepath[100];
	scanf("%s",filepath);
	send(sockfd,filepath,strlen(filepath),0);
	printf(">>>input upload filename:");
	char filename[100];
	scanf("%s",filename);
	send(sockfd,filename,strlen(filename),0);
	printf(">>>input password:");
	char password[20];
	scanf("%s",password);
	send(sockfd,password,strlen(password),0);
	//接收服务器发的success or failure
	bzero(recv_buf,sizeof(recv_buf));
	recv(sockfd,recv_buf,sizeof(recv_buf),0);
	printf("%s\n",recv_buf);
}

void download()
{
	//发名字
	//printf("download\n");
	printf(">>>input download file owner:");
	char owner[50];
	scanf("%s",owner);
	send(sockfd,owner,strlen(owner),0);
	printf(">>>input download file name:");
	char filename[100];
	scanf("%s",filename);
	send(sockfd,filename,strlen(filename),0);
	printf(">>>input upload file path:");
	char filepath[100];
	scanf("%s",filepath);
	send(sockfd,filepath,strlen(filepath),0);
	if(strcmp(owner,id)!=0)
	{
		printf(">>>input download file password(4):");
		char password[50];
		scanf("%s",password);
		send(sockfd,password,strlen(password),0);
	}
	//收反馈消息
	bzero(recv_buf,sizeof(recv_buf));
	recv(sockfd,recv_buf,sizeof(recv_buf),0);
	if(strcmp("nameerror",recv_buf)==0)	printf("NAME ERROR\n");
	else//接收反馈消息
	{
		bzero(recv_buf,sizeof(recv_buf));
		recv(sockfd,recv_buf,sizeof(recv_buf),0);
		if(strcmp(recv_buf,"passworderror")==0)	printf("PASSWORD ERROR\n");
		else	printf("%s\n",recv_buf);
	}
}

void checkdir()
{
	bzero(recv_buf,sizeof(recv_buf));
	recv(sockfd,recv_buf,sizeof(recv_buf),0);
	printf("网盘中文件如下:\n%s\n",recv_buf);
}

void hjlogin()
{
	//登陆
	printf(">>>input your name:");
	scanf("%s",send_buf);
	bzero(id,sizeof(id));
	strcpy(id,send_buf);
	send(sockfd,send_buf,strlen(send_buf),0);
	bzero(send_buf,sizeof(send_buf));
	printf("\n>>>input your password:");
	scanf("%s",send_buf);
	send(sockfd,send_buf,strlen(send_buf),0);
	bzero(send_buf,sizeof(send_buf));
	//验证
	bzero(recv_buf,sizeof(recv_buf));
	recv(sockfd,recv_buf,sizeof(recv_buf),0);
	char success[20]="LOGINSUCCESS";
	if(strcmp(recv_buf,success)==0)
	{
		int flag=0;
		printf("\n\nLOG IN SUCCESS\n\n");
		while(1)
		{
			//功能菜单 上传/下载/查看目录
			printf("\t功能\n");
			printf("\t1.upload\n");
			printf("\t2.download\n");
			printf("\t3.check directory\n");
			printf("\t4.back\n");
			int select=0;
			scanf("%d",&select);
			bzero(send_buf,sizeof(send_buf));
			send_buf[0]='*';
			switch(select)
			{
			case 1:send_buf[1]='1';break;
			case 2:send_buf[1]='2';break;
			case 3:send_buf[1]='3';break;
			case 4:send_buf[1]='4';break;
			}
			send_buf[2]='*';
			send(sockfd,send_buf,strlen(send_buf),0);
			bzero(send_buf,sizeof(send_buf));
			switch(select)
			{
			case 1:upload();break;//上传
			case 2:download();break;//下载
			case 3:checkdir();break;//查看目录
			case 4:flag=1;break;//退出
			}
			if(flag) break;
		}
	}
	else printf("用户名或密码不正确\n");
}

void menu()
{
	int flag=0;
	while(1)
	{
		printf("\t菜单\n");
		printf("\t1.register\n");
		printf("\t2.log in\n");
		printf("\t3.exit\n");
		int select=0;
		scanf("%d",&select);
		bzero(send_buf,sizeof(send_buf));
		send_buf[0]='*';
		switch(select)
		{
		case 1:send_buf[1]='1';break;
		case 2:send_buf[1]='2';break;
		case 3:send_buf[1]='3';break;
		}
		send_buf[2]='*';
		send(sockfd,send_buf,strlen(send_buf),0);
		bzero(send_buf,sizeof(send_buf));
		switch(select)
		{
		case 1:hjregister();break;//注册
		case 2:hjlogin();break;//登陆
		case 3:flag=1;break;//退出
		}
		if(flag) break;
	}
}

int main(int argc, char *argv[])
{
	setclient();
	menu();
	close(sockfd);
	return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值