Linux---简单的ftp服务器

在Linux下设计一组简单的ftp服务器。

主要功能如下:

1、一台服务器,可同时连接多台客户端实现相同功能操作。

2、客户端可访问服务器的所含文件,并从服务端下载所需文件;同时客户端可以将自身所含文件发送到服务器。

3、客户端可以查看自身所含文件。

//config.h

#define LS     0
#define PWD    1
#define GET    2
#define IFGO   3
#define CD     4
#define QUIT   5
#define LLS    6
#define LCD    7
#define PUT    8
#define DOFILE 9


struct Msg
{
        int type;
        char data[1024];
        char secondBuf[128];//该字符串空间主要用于备用存储
};
~                                                                                                 
//客户端代码

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include "config.h"

int get_msg_type(char *cmd)
{

        if(!strcmp(cmd,"ls"))               return LS;
        if(!strcmp(cmd,"pwd"))              return PWD;
        if(!strcmp(cmd,"quit"))             return QUIT;
        if(!strcmp(cmd,"lls"))              return LLS;

        if(strstr(cmd,"lcd") != NULL)       return LCD;
        if(strstr(cmd,"cd") != NULL)        return CD;
        if(strstr(cmd,"put") != NULL )      return PUT;
        if(strstr(cmd,"get") != NULL)       return GET;

        return -1;

}

char* getDesDir(char* msg) //该函数调用后将破坏原msg数据的格式
{
        char *dir;
        dir = strtok(msg," ");
        dir = strtok(NULL," ");
        return dir;
}

int handler_msg(struct Msg msg,int fd)
{

        char *dir = NULL;
        char readBuf[1024] = {0};
        char buf[32];
        int filefd;
        int ret = get_msg_type(msg.data);

        switch(ret){
                case CD:
                case LS:
                case PWD:
                case GET:
                        write(fd,&msg,sizeof(msg));
                        break;

                case PUT:
                        strcpy(buf,msg.data); //在此需要调用strcpy函数对data备份;否则put指令无法执行
                        dir = getDesDir(buf);
                        if(access(dir,F_OK)  == -1){
                                printf("This file is not exist\n");
                                break;
                        }else{
                                filefd = open(dir,O_RDWR);
                                read(filefd,msg.secondBuf,sizeof(msg.secondBuf));
                                close(filefd);
                                write(fd,&msg,sizeof(msg));
                                break;
                        }

                case LLS:
                        system("ls");
                        break;

                case LCD:
                        dir = getDesDir(msg.data);
                        printf("dir= %s\n",dir);
                        chdir(dir);
                        break;

                case QUIT:
                        printf("quit\n");
                        strcpy(msg.data,"quit");
                        write(fd,&msg,sizeof(msg));
                        exit(-1);
        }
        return ret;
}


void server_msg(int fd,struct Msg msg)
{
        int n_read;
        int newfilefd;
        struct Msg msgget;

        n_read = read(fd,&msgget,sizeof(msgget));

        if(n_read == 0){
                printf("server is quit\n");
                exit(-1);
        }

        if(msgget.type == DOFILE){
                char* p = getDesDir(msg.data);
                newfilefd = open(p,O_RDWR|O_CREAT|0600);
                write(newfilefd,msgget.data,strlen(msgget.data));
                close(newfilefd);
                fflush(stdout);
        }else{
                printf("=======================\n");
                printf("%s\n",msgget.data);
                printf("=======================\n");
                fflush(stdout);
        }

}

int main(int argc,char** argv)
{
        if(argc != 3){
                printf("The parmas is not good\n");
                exit(-1);
        } //输入参数判断(服务器端同)

        int c_fd;
        int ret;

        struct sockaddr_in c_addr;
        struct Msg msg;

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

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

        c_addr.sin_family = AF_INET;
        c_addr.sin_port =htons(atoi(argv[2]));
        inet_aton(argv[1],&c_addr.sin_addr);

        if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in)) == -1){
                perror("connect\n");
                exit(-1);
        }

        printf("connect...\n"); 

        while(1){
                memset(&msg.data,0,sizeof(msg.data));
                gets(msg.data);
                ret = handler_msg(msg,c_fd);

                if(ret == -1){
                        printf("This command is not exist\n");
                        fflush(stdout);
                        continue;

                }else if(ret > IFGO){
                        fflush(stdout);
                        continue;
                }

                server_msg(c_fd,msg);

        }
        return 0;
}
//服务端代码

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

int get_msg_type(char* data)
{

        if(!strcmp(data,"ls"))                  return LS; 
        if(!strcmp(data,"pwd"))                 return PWD;
        if(!strcmp(data,"quit"))                return QUIT;

        if(strstr(data,"cd") != NULL)           return CD; 
        if(strstr(data,"get") != NULL)          return GET;
        if(strstr(data,"put") != NULL)          return PUT;

        return -1; 
}

char* getdir(char* msg)
{
        char* dir;
        dir = strtok(msg," ");
        dir = strtok(NULL," ");
        return dir;
}


void handler_msg(int fd,struct Msg msg)
{
        char* File = NULL;
        FILE* r;
        int filefd;
        char readBuf[1024] = {0};
        char* dir = NULL;

        printf("cmd: %s\n",msg.data);

        int ret = get_msg_type(msg.data);
        switch(ret){
        case LS:
        case PWD:
                r = popen(msg.data,"r");
                fread(msg.data,sizeof(msg.data),1,r);
                write(fd,&msg,sizeof(msg));
                break;

        case CD:
                dir = getdir(msg.data);
                printf("dir:%s\n",dir);
                chdir(dir);
                break;

        case GET:
                File = getdir(msg.data);
                if(access(File,F_OK) == -1){
                        strcpy(msg.data,"This file is not exist\n");
                        write(fd,&msg,sizeof(msg));
                }else{
                        msg.type = DOFILE;
                        filefd = open(File,O_RDWR);
                        read(filefd,readBuf,sizeof(readBuf));
                        close(filefd);
                        strcpy(msg.data,readBuf);
                        write(fd,&msg,sizeof(msg));
                }
                break;

        case PUT:
                filefd = open(getdir(msg.data),O_RDWR|O_CREAT,0600);
                write(filefd,msg.secondBuf,strlen(msg.secondBuf));
                close(filefd);
                break;

        case QUIT:
                printf("quit\n");
                exit(-1);
        }
}


int main(int argc,char** argv)
{
        if(argc != 3){
                printf("The params is not good\n");
                exit(-1);
        }

        struct Msg msg;
        struct sockaddr_in s_addr;
        struct sockaddr_in c_addr;

        int sockfd;
        int c_fd;
        int size = sizeof(struct sockaddr_in);
        int n_read;
        int ret;
        pid_t pid;

        memset(&s_addr,0,sizeof(struct sockaddr_in));
        memset(&c_addr,0,sizeof(struct sockaddr_in));
        memset(&msg,0,sizeof(struct Msg));

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

        s_addr.sin_family = AF_INET;
        s_addr.sin_port = htons(atoi(argv[2]));
        inet_aton(argv[1],&s_addr.sin_addr);

        if(bind(sockfd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in)) == -1){
                perror("bind\n");
                exit(-1);
        }

        listen(sockfd,10);

        while(1){
                if((c_fd = accept(sockfd,(struct sockaddr *)&c_addr,&size)) == -1){
                        perror("accept\n");
                        exit(-1);
                }

                printf("%s:connect success\n",inet_ntoa(c_addr.sin_addr));

                pid = fork();
                if(pid == -1){
                        perror("fork\n");
                }else if(pid == 0){
                        while(1){
                                memset(&msg.data,0,sizeof(msg.data));
                                n_read = read(c_fd,&msg,sizeof(msg));
                                if(n_read == 0){
                                        printf("quit\n");
                                        break;
                                }
                                else if(n_read > 0){
                                        handler_msg(c_fd,msg);

                                }
                        }
                }

        }

        return 0;
}

服务器与客户端的互动需要各个指令的相互配合:

        一、服务器可以连接多个客户端,因此只有在客户端成功接入时,创建子进程对客户端进行处理。

        二、有多个指令的处理形式是相同的因此可以对它们进行归纳处理:

                1、ls pwd指令:对于客户端来说,只需要调用popen函数将其实现的结果发送给客户端打印即可。

                2、lls lcd都属于客户端自身的调用,与服务器无关。

                3、quit指令,对于服务器来说需要知晓该客户端的退出,需要退出为该客户端服务的子进程;对于客户端则直接退出即可。

                4、cd指令,需要通过解析cd指令的具体操作目标,因此需要getDesDir函数对传送的指令进行解析,做出具体操作。在客户端使用该函数的时候,需要特别注意,在对put指令解析时:会对原msg.data产生分割,所以当在此把msg.data中的内容发送至服务器的时候,服务器将无法判断。

                5、get、put指令是客户端与服务器/服务器与客户端之间的文件收发操作。特别注意:在操作相应的文件时,解析后务必要使用access()函数对待操作文件的存在与否进行判断。

补充:get命令从服务器获取文件时,发现在客户端打开该文件内容为空,是由于本地客户端缺少对该文件的访问权限,使用chmod命令修改权限即可显示源文件内容。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
ASP.NET FTP系统源代码是一种用于在ASP.NET平台上实现FTP功能的源代码。FTP(文件传输协议)是一种用于在计算机之间传输文件的标准协议。 ASP.NET是一种用于构建Web应用程序的微软技术,它使用具有服务器端脚本语言的服务器技术来生成动态网页。 ASP.NET FTP系统源代码通常包含以下功能: 1. 用户认证:允许用户通过用户名和密码进行身份验证,以便访问FTP服务器。 2. 目录浏览:显示FTP服务器上的文件和文件夹列表,以便用户可以浏览和查询。 3. 文件上传:允许用户将文件从本地计算机上传到FTP服务器上的指定位置。 4. 文件下载:允许用户从FTP服务器上下载文件到本地计算机上的指定位置。 5. 文件删除:允许用户删除FTP服务器上的文件。 6. 文件重命名:允许用户更改FTP服务器上文件的名称。 7. 目录创建和删除:允许用户在FTP服务器上创建和删除目录。 8. 权限控制:允许管理员对用户进行权限管理,例如授权用户只能上传文件而不能删除或下载文件。 9. 日志记录:记录所有FTP操作和事件,以便跟踪和故障排除。 ASP.NET FTP系统源代码可以使用C#或VB.NET等编程语言编写,并使用FTP客户端库,如System.Net.FtpClient命名空间提供的类来实现FTP功能。 开发人员可以根据自己的需求对ASP.NET FTP系统源代码进行定制和扩展,以满足特定的业务需求。他们可以添加额外的功能,如文件搜索、文件夹权限管理等。 总之,ASP.NET FTP系统源代码是实现FTP功能的一种解决方案,可用于构建功能完善的FTP服务器客户端应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值