Linux 网络编程笔记 [2] —— FTP服务C代码 version2

原创首发于CSDN,转载请注明出处,谢谢!



前言

该篇博文是上一篇文章 Linux 网络编程笔记 [1] —— 套接字 Socket 实现最简版 FTP 服务(C语言)里FTP服务的第二种实现。在源代码框架大致相同的情况下,些许细节微微不同或许还有一点点粗糙,对此笔者也不再继续做优化了。另外,在此特别感谢「哞哞教育」江兴畿讲师的辛苦讲解。


服务端代码 service.c

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

int change(char *cmd);
char *getbehind(char *cmd);
void getmessage(char cmd[128], int cfd);
void chooseCmd(char cmd[128], int c_fd);

int main(int argc,char **argv)
{
	int s_fd;
	int c_fd;
	int s_read;

	char Writebuf[128];
	char Readbuf[128];
	
	struct sockaddr_in s_addr;
	struct sockaddr_in c_addr;

	if(argc != 3){
		perror("argc");
		exit(-1);
	}
		
	//1.socket
	s_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(s_fd == -1){
		perror("socket");
		exit(-1);
	}
	
	memset(&s_addr, 0, sizeof(struct sockaddr_in));
	
	s_addr.sin_family = AF_INET;
	s_addr.sin_port   = htons(atoi(argv[2]));
	inet_aton(argv[1], &s_addr.sin_addr);
	
	//2.bind
	bind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));
	
	//3.listen
	listen(s_fd, 10);
	printf("等待客户端的连接……\n");
	memset(&c_addr, 0, sizeof(struct sockaddr_in));

	int clen = sizeof(struct sockaddr_in);

	while(1){
		//4.accept
		c_fd = accept(s_fd, (struct sockaddr *)&c_addr, &clen);
		if(c_fd == -1){
			perror("accept");
			exit(-1);
		}
		printf("与客户端取得连接:%s.\n",inet_ntoa(c_addr.sin_addr));
		
		//5.read & write cycle.
		if(fork() == 0){
			while(1){
				memset(Readbuf, 0, sizeof(Readbuf));
				//服务端处于被动状态,等待来自客户端的指令。
				s_read = read(c_fd, Readbuf, 128);
				if(s_read == 0){
					printf("The client exits directly!\n");
					break;
				}else if(s_read > 0){
					chooseCmd(Readbuf,c_fd);
					memset(Readbuf,0,sizeof(Readbuf));
				}
			}
		}
	}
	close(c_fd);
	close(s_fd);
	return 0;
}


void chooseCmd(char cmd[128],int c_fd)
{
	int  sfd;
	FILE *fdb;
	char *readbuf = (char*)malloc(128);	
	char freadbuf[128];
	char *p = (char *)malloc(8000);
	
	int ret = change(cmd);
	switch(ret){
		case 1:
			//函数popen与函数open的差异?
			fdb =  popen("ls", "r");
			fread(freadbuf, sizeof(freadbuf), 1, fdb);
			write(c_fd, freadbuf, sizeof(freadbuf));
			memset(freadbuf, 0, sizeof(freadbuf));	
			printf("ls ok.\n");
			break;
		case 2: 
			//了解ps命令。
			system("ps");
			printf("ps ok.\n");
			break;	
		case 3:
			p = getbehind(cmd);
			chdir(p);
			memset(p, 0, sizeof(p));
			break;
		case 4:
			read(c_fd, freadbuf, sizeof(freadbuf));
			printf("%s\n",freadbuf);
			exit(1);
			break;
		case 5://get
			readbuf = getbehind(cmd);
			if(access(readbuf, F_OK) == -1){
				write(c_fd, "NO file", strlen("NO file"));
			}else{
				sfd = open(readbuf, O_RDWR, 0666);
				read(sfd, p, 8000);
				write(c_fd, p, strlen(p));
				close(sfd);
				memset(p, 0, 8000);
			}
			break;
		case 6: //put 	
			getmessage(cmd, c_fd);
			break;
	}
}


int change(char *cmd)
{
	if(!strcmp("ls",cmd))		        {return 1;}		
	else if(!strcmp("ps",cmd))	        {return 2;}
	else if(strstr(cmd,"cd")!=NULL)	    {return 3;}
	else if(!strcmp("g",cmd))           {return 4;}				   
	else if(strstr(cmd,"get")!=NULL)    {return 5;} 
	else if(strstr(cmd,"put")!=NULL)    {return 6;}
}

char *getbehind(char *cmd)
{	
	char *p;
	p = strtok(cmd,  " ");
	p = strtok(NULL, " ");
	return p;
}

void getmessage(char cmd[128],int cfd)
{
	char readbuf[8000];
	char *p = getbehind(cmd);
	read(cfd, readbuf, 8000);
	int fd = open(p, O_RDWR|O_CREAT, 0666);

	write(fd, readbuf, strlen(readbuf));
	printf("receive successfully\n");
	close(fd);
	memset(readbuf,0,8000);
}


客户端代码 client.c

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

int change(char cmd[128]);          
char *getbehind(char cmd[128]);
void getmessage(char *cmd,int cfd);
void putmessage(char cmd[128],int c_fd);
void chooseCmd(char *cmd, int c_fd);

int main(int argc,char **argv)
{
	int c_fd;
	int nread;
	
	char Readbuf[1024];
	char Writebuf[128];
	char buf[256];

	struct sockaddr_in c_addr;
	
	if(argc != 3){
		perror("argc error");
		exit(-1);
	}

	c_fd =  socket(AF_INET, SOCK_STREAM, 0);
	if(c_fd == -1){
		perror("socket");
		exit(-1);
	}

	memset(&c_addr,0,sizeof(struct sockaddr_in));

	c_addr.sin_family = AF_INET;
	c_addr.sin_port = htons(atoi(argv[2]));
	inet_aton(argv[1],&c_addr.sin_addr);
	
	int clent = sizeof(struct sockaddr_in);
	if( (connect(c_fd,(struct sockaddr *)&c_addr,clent)) == -1){
		perror("connect");
		exit(-1);
	}

	printf("与服务端建立连接中……\n");
	while(1){
		gets(Writebuf);
		printf("Client's cmd:%s\n",Writebuf);
		write(c_fd,Writebuf,strlen(Writebuf));
		chooseCmd(Writebuf,c_fd);
		printf("***************Cmd Send Over.***************\n");
		memset(Writebuf,0,strlen(Writebuf));
	}
	return 0;
}

int change(char cmd[128])
{
	if(!strcmp("lls",cmd))		           {return 1;}
	else if(strstr(cmd,"lcd")!=NULL)	   {return 2;}
	else if(!strcmp("g",cmd))		       {return 3;}

	else if(!strcmp("ls",cmd))             {return 4;}
	else if(strstr(cmd,"cd")!=NULL)        {return 5;}
	else if(strstr(cmd,"get")!=NULL)	   {return 6;}     
	else if(strstr(cmd,"put")!=NULL)       {return 7;}
}              

char *getbehind(char cmd[128])
{
	char *p;
	p = strtok(cmd,  " ");
	p = strtok(NULL, " ");
	return p;
}

void chooseCmd(char *cmd, int c_fd)
{
	FILE *fdb;
	int  ret = change(cmd);
	char freadbuf[128];
	char *p = (char *)malloc(8001);

	switch(ret){
		case 1: 
			system("ls"); //lls
			break;

		case 2:
			p = getbehind(cmd); //lcd
			chdir(p);
			memset(p,0,8000);
			break;

		case 3: 
			printf("unconnecting\n");  //g
			write(c_fd,"away host",128);
			close(c_fd);
			exit(-1);
			break;
		case 4:	
			read(c_fd,p,1024);    //ls
			printf("%s\n",p);                       
			memset(p,0,1024);
			break;
		case 5:
			printf("host folder open or exit successful\n"); //cd
			break;	
		case 6: 
			getmessage(cmd,c_fd);   //get
			break;
		case 7: 
			putmessage(cmd,c_fd);  //put
			break;
		default:
            printf("Cmd error!\n");
            break;
	}
}

void getmessage(char *cmd,int cfd)
{
	int fd;
	char readbuf[8000];
	char *p = getbehind(cmd);
	
	read(cfd, readbuf, 8000);
	if(strlen(readbuf) != strlen("NO file")){	
		fd = open(p,O_RDWR|O_CREAT,0666);
		write(fd,readbuf,strlen(readbuf));
		printf("receive successfully\n");
		close(fd);
		memset(readbuf,0,8000);
	}else{
		printf("NO this file!\n");
	}
}

void putmessage(char cmd[128],int c_fd)
{
	int sfd;
	char *p = (char *)malloc(8000);
	memset(p, 0, 8000);

	char *readbuf = (char *)malloc(128);
	readbuf = getbehind(cmd);

	if(access(readbuf, F_OK) == -1){
		printf("No file.\n");
	}else{
		sfd = open(readbuf,O_RDWR,0666);
		read(sfd,p,8000);
		write(c_fd,p,strlen(p));
		close(sfd);
		memset(p, 0, 8000);
	}
}


文章更新记录

  • 文章完成。「2022.7.1 22:27」
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值