【Linux系统编程项目】实现部分FTP功能

项目功能

服务器相关

1.获取服务器文件,get xxx
2.展示服务器有哪些文件 ,ls
3.进入服务器文件夹 cd
4.上传文件到服务器

客户端相关

lls查看客户端本地文件
lcd 进入客户端xx文件夹
lpwd 查看客户端当前目录

项目代码

客户端代码(代码较长,懒得分文件编了)
已上传资源,需要可以下载一波
https://download.csdn.net/download/qq_52749711/88233816

部分服务器代码

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

#define SERVER_IP		"127.0.0.1"	
#define SERVER_PORT		8888
#define RECV_MAX_LEN	128	
#define SEND_MAX_LEN	4096

#define LS		0
#define LL		1
#define CD		2
#define PWD     3
#define QUIT    4
#define GET		5


//………………………………省略处理命令的代码

int is_command(char *buf)
{
    
    	
	printf("buf = %s\n",buf);
	char *token = strtok(buf, " ");
	char *ptr = token;

	printf("ptr = %s\n",ptr);

	if(!strcmp(ptr,"ls")) return LS;

	if(!strcmp(ptr,"ll")) return LL;

	if(!strcmp(ptr,"pwd")) return PWD;

	if(!strcmp(ptr,"cd"))	return CD;

	if(!strcmp(ptr,"get"))	return GET;
	
	if(!strcmp(ptr,"quit")) return QUIT;

	return -1;
}

void client_handler(int client_sockfd,int client_pid)
{
    
    
	char *buffer = NULL;
	char *buffer_err = NULL;
	int i = 0;
	int cmd = 0;

	//开辟接收需要的空间
	buffer = (char *)malloc(sizeof(char) * RECV_MAX_LEN);
	if(buffer == NULL){
    
    
		printf("recv malloc fail\n");
		exit(-1);
	}

	while(1){
    
    
		memset(buffer,'\0',RECV_MAX_LEN);
		if(recv(client_sockfd, buffer, RECV_MAX_LEN, 0) > 0){
    
    

			//调试信息
			printf("from client msg:%s\n",buffer);	

			//调用函数判断是否有此命令
			if((cmd = is_command(buffer)) < 0){
    
    

				//申请错误信息空间,存放错误信息
				buffer_err = (char *)malloc(sizeof(char) * RECV_MAX_LEN + 100);
				sprintf(buffer_err,"command:\" %s \",not found\nyour try :ls ll cd get……\n",buffer);

				//发送错误信息给客户端
				send(client_sockfd, buffer_err, strlen(buffer_err), 0);

				//释放空间防止泄露
				free(buffer_err);
				buffer_err = NULL;
			}
			//处理命令函数,并如果是退出命令则break退出进程
			if(command_handler(client_sockfd,cmd) == QUIT) {
    
    
				free(buffer);
				buffer = NULL;
				close(client_sockfd);
				break;
			}
		}
	}
	printf("\nclient %d quit.\n",client_pid);
}

//主函数
int main()
{
    
    
	struct sockaddr_in server_addr;
	int sockfd;

	int client_sockfd;
	struct sockaddr_in client_address;
	socklen_t client_len = sizeof(client_address);


	int count = 0;
	//int socket(int domain, int type, int protocol);
	// 创建套接字
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0) {
    
    
		perror("server sockt runing fail\n");
		exit(EXIT_FAILURE);
	}
	//清空servoer_addr内存
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(SERVER_PORT);
	server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);

	//绑定端口
	if ((bind(sockfd, (struct sockaddr*) &server_addr, sizeof(server_addr))) < 0) {
    
    
		perror("server bind fail\n");
		exit(EXIT_FAILURE);
	}

	//监听
	if (listen(sockfd, 10) < 0) {
    
    
		perror("监听失败");
		exit(EXIT_FAILURE);
	}

	//	int client_sockfd;
	//	struct sockaddr_in client_address;
	//	socklen_t client_len = sizeof(client_address);

	while(1){
    
    
		printf("wait client accept……\nnow client count is %d\nyou can use Ctrl+C to Stop Server\n",count++);
		client_sockfd = accept(sockfd, (struct sockaddr *)&client_address, &client_len);

		if (client_sockfd < 0) {
    
    
			perror("连接失败,联系客服解决");
		}else{
    
    
			//子进程处理客户端请求
			if(fork() == 0){
    
    
				client_handler(client_sockfd,getpid());	
				exit(0);
			}else{
    
    }
		}
	}


	return 0;
}

客户端代码

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

#define SERVER_IP  		127.0.0.1     
#define SERVER_PORT    8888

#define SEND_MAX_LEN	128
#define RECV_MAX_LEN	4096

//本地命令
int is_command(char *send_buf)
{
    
    

	char lcd_path[128];
	
	if(!strcmp(send_buf,"lls")){
    
    
		system("ls");
		return 1;
	}  

	if(!strcmp(send_buf,"lcd")){
    
    
		memset(lcd_path,'\0',128);
		scanf("%s",lcd_path);
		//切换当前工作路径函数
		chdir(lcd_path);
		system("pwd");
		return 1;
	}

	if(!strcmp(send_buf,"lpwd")){
    
    
		system("pwd");
		return 1;
	}
	return 0;
}

int main()
{
    
    	
	struct sockaddr_in server_address;
	int sockfd;

	int pid = getpid();
	char *send_buf = NULL;
	char *recv_buf = NULL;

	int get_filefd;				//get命令的文件标识
	int get_flag = 0;			//get命令flag
	char get_path[32]; 			//get命令文件名

	sockfd = socket(AF_INET, SOCK_STREAM, 0);

	memset(&server_address, 0, sizeof(server_address));
	server_address.sin_family = AF_INET;
	server_address.sin_port = htons(SERVER_PORT);
	server_address.sin_addr.s_addr = inet_addr("127.0.0.1");

	// connect是阻塞函数,它会等待服务器的响应
	// 返回值为0表示连接成功,-1表示连接失败
	if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
    
    
		perror("连接失败");
		exit(EXIT_FAILURE);
	}else{
    
    
		printf("连接成功\r\n");
		send_buf = (char *)malloc(sizeof(char)*SEND_MAX_LEN);
		recv_buf = (char *)malloc(sizeof(char)*RECV_MAX_LEN);		
		while(1){
    
    
			memset(send_buf,'\0',SEND_MAX_LEN);
			memset(recv_buf,'\0',RECV_MAX_LEN);

			printf("\ninput cmd:");
			scanf("%s",send_buf);

			//判断是否为本地命令
			if(is_command(send_buf) == 0){
    
    

				send(sockfd, send_buf, strlen(send_buf), 0);

				int re = recv(sockfd, recv_buf, RECV_MAX_LEN, 0);

				//printf("->%s\nre = %d\n",recv_buf,re);

				//当我输入get之后第二个参数一定是文件名,捕获文件名创建
				if(get_flag == 1){
    
    
					sprintf(get_path,"./%s",send_buf);

					printf("get_path=%s\n",get_path);
					get_filefd = open((const char *)get_path,O_CREAT|O_RDWR|O_EXCL,0666);
					if(get_filefd == -1 ){
    
    
						printf("\ncreate file fail or file exist \n");	
						get_flag = 0;
					}else{
    
    
						lseek(get_filefd,0,SEEK_SET);

						//将数据写入文件
						write(get_filefd,recv_buf,strlen(recv_buf));
						close(get_filefd);
						get_flag = 0;
					}
				}
				printf("\nmsg from server\n##################\n%s\n##################\n\n",recv_buf);

				if(!strcmp(send_buf,"get")) get_flag = 1;

				if(!strcmp(recv_buf,"quit")){
    
    
					free(send_buf);
					free(recv_buf);
					send_buf = NULL;
					recv_buf = NULL;
					break;
				}
			}//is_command
		}//while(1)
	}

	close(sockfd);
	return 0;
}

结束

如有问题,欢迎提出,共同进步

猜你喜欢

转载自blog.csdn.net/qq_52749711/article/details/132368905