Ftp服务器程序


/*============================================================================
 Name        : FtpServer.cbp
 Author      : Haier
 Version     : 1.01
 Copyright   : Copyright (c) 2014
 Description : Ftp Server in C, Ansi-style, Compile by Gcc,in Linux
 ============================================================================*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>//sockaddr_in等结构的定义
#include <netdb.h>     //addrinfo等结构的定义
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

#define LISTEN_PORT (5500)
#define BUFFER      (1024)
#define TRUE        (1)

char CurrentDirPath[100];
char CurrentDirName[25];
char help[]=
"get    get a file from server\n\
 put    upload a file to server\n\
 pwd    display    the current directory of server\n\
 dir    display the files in the current directory of server\n\
 cd     change the directory of server\n\
 ?      display the whole command which equals 'help'\n\
 quit   return\n";

char *getDirName(char *dirPathName);
void pwd(int sock);
void dir(int sock);
void cd(int sock,char *DirName);
void cdback(int sock);
void Help(int sock);
void put(int sock,char *FileName);
void get(int sock,char *FileName);


int main(int argc,char *argv[])
{

    int sock,sockmsg;
    int lengthOfSock,lengthOfSockMsg;
    int DataOfsock,DataOfsockmsg;
    pid_t Child;
    char ClientCmd[10],CmdArg[20];
    int LengthOfRead=0;

    struct sockaddr_in Server,ServerMsg;

    sock=socket(AF_INET,SOCK_STREAM,0);
    sockmsg=socket(AF_INET,SOCK_STREAM,0);
    if(sock<0 || sockmsg<0)
    {
        perror("Socket Failed !\n");
        exit(1);
    }

    Server.sin_family=AF_INET;
    Server.sin_port  =htons(LISTEN_PORT);
    Server.sin_addr.s_addr=INADDR_ANY;

    ServerMsg.sin_family=AF_INET;
    ServerMsg.sin_port  =htons(LISTEN_PORT+1);
    ServerMsg.sin_addr.s_addr=INADDR_ANY;

    if(bind(sock,(struct sockaddr *)&Server,sizeof(Server))<0
    || bind(sockmsg,(struct sockaddr *)&ServerMsg,sizeof(ServerMsg))<0)
    {
        perror("Bind Failed !\n");
        exit(1);
    }

    lengthOfSock=sizeof(Server);
    lengthOfSockMsg=sizeof(ServerMsg);

    if(getsockname(sock,(struct sockaddr *)&Server,&lengthOfSock)<0
    || getsockname(sockmsg,(struct sockaddr *)&ServerMsg,&lengthOfSockMsg)<0)
    {
        perror("GetSockName Fail !\n");
        exit(1);
    }

    printf("Socket port # %d  %d\n",ntohs(Server.sin_port),ntohs(ServerMsg.sin_port));

    memset(CurrentDirPath,0,sizeof(CurrentDirPath));
    getcwd(CurrentDirPath,sizeof(CurrentDirPath));

    listen(sock,2);
    listen(sockmsg,2);

    do
    {
        DataOfsock=accept(sock,(struct sockaddr *)0,(int *)0);
        DataOfsockmsg=accept(sockmsg,(struct sockaddr *)0,(int *)0);

        if(DataOfsock==-1 || DataOfsockmsg==-1)
        {
            perror("Accept Failed !\n");
        }
        else
        {
            if((Child=fork())==-1)
            {
                perror("Fork Failed !\n");
            }

            //child process
            if(Child==0)
            {
                printf("Connection Succeed ! Client is Coming.\n");

loop:           memset(ClientCmd,0,sizeof(ClientCmd));
                LengthOfRead=read(DataOfsockmsg,ClientCmd,sizeof(ClientCmd));

                if(LengthOfRead<0)
                {
                    perror("Read Failed !\n");
                }
                else if(LengthOfRead==0)
                {
                    printf("Connection Closed !\n");
                    close(DataOfsock);
                    close(DataOfsockmsg);
                }
                else
                {
                    if(strcmp(ClientCmd,"pwd")==0)
                    {
                        pwd(DataOfsock);
                        goto loop;
                    }
                    else if(strcmp(ClientCmd,"dir")==0)
                    {
                        dir(DataOfsock);
                        goto loop;
                    }
                    else if(strcmp(ClientCmd,"cd")==0)
                    {
                        memset(CmdArg,0,sizeof(CmdArg));
                        read(DataOfsockmsg,CmdArg,sizeof(CmdArg));
                        cd(DataOfsock,CmdArg);
                        goto loop;
                    }
                    else if(strcmp(ClientCmd,"cd ..")==0)
                    {
                        cdback(DataOfsock);
                        goto loop;
                    }
                    else if(strcmp(ClientCmd,"get")==0)
                    {
                        memset(CmdArg,0,sizeof(CmdArg));
                        read(DataOfsockmsg,CmdArg,sizeof(CmdArg));
                        get(DataOfsock,CmdArg);
                        goto loop;
                    }
                    else if(strcmp(ClientCmd,"put")==0)
                    {
                        memset(CmdArg,0,sizeof(CmdArg));
                        read(DataOfsockmsg,CmdArg,sizeof(CmdArg));
                        put(DataOfsock,CmdArg);
                        goto loop;
                    }
                    else if(strcmp(ClientCmd,"?")==0)
                    {
                        Help(DataOfsock);
                        goto loop;
                    }
                    else if(strcmp(ClientCmd,"quit")==0)
                    {
                        printf("Connection Closed !\n");
                        close(DataOfsock);
                        close(DataOfsockmsg);
                        exit(0);
                    }
                    else
                    {
                        goto loop;
                    }
                }
            }
        }
    }while(TRUE);

    return 0;
}

char *getDirName(char *dirPathName)
{
    int i,Length;
    int Position;
    char *DirName;

    if(dirPathName==NULL)
    {
        printf("Absoultly Path is NULL !\n");
        return NULL;
    }

    Length=strlen(dirPathName);
    for(i=Length-1; i>=0; i--)
    {
        if(dirPathName[i]=='/')
        {
            Position=i;
            break;
        }
    }

    DirName=(char *)malloc(sizeof(char)*(Length-Position+1));
    for(i=Position+1; i<Length; i++)
    {
        DirName[i-Position-1]=dirPathName[i];
    }

    return DirName;
}

void pwd(int sock)
{
    char *PtrToDirName;

    memset(CurrentDirPath,0,sizeof(CurrentDirPath));
    getcwd(CurrentDirPath,sizeof(CurrentDirPath));
    PtrToDirName=getDirName(CurrentDirPath);
    strcpy(CurrentDirName,PtrToDirName);
    write(sock,CurrentDirName,strlen(CurrentDirName)+1);
}

void dir(int sock)
{
    DIR *PtrToDir;
    struct dirent *Pent;
    int FileCount=0;
    int i,fd;
    char FileName[30],FileInfo[50],FilePath[100];
    struct stat FileStat;

    PtrToDir=opendir(CurrentDirPath);
    Pent    =readdir(PtrToDir);

    while(Pent!=NULL)
    {
        FileCount++;
        Pent=readdir(PtrToDir);
    }

    write(sock,&FileCount,sizeof(int));
    closedir(PtrToDir);

    if(FileCount<0)
    {
        return;
    }
    else
    {
        PtrToDir=opendir(CurrentDirPath);

        for(i=0; i<FileCount; i++)
        {
            Pent=readdir(PtrToDir);
            memset(FileName,0,sizeof(FileName));
            memset(FileInfo,0,sizeof(FileInfo));
            strcpy(FileName,Pent->d_name);

            //check the file is a directory or a file
            memset(FilePath,0,sizeof(FilePath));
            strcpy(FilePath,CurrentDirPath);
            strcat(FilePath,"/");
            strcat(FilePath,FileName);
            fd=open(FilePath,O_RDONLY,S_IREAD);

            fstat(fd,&FileStat);

            if(S_ISDIR(FileStat.st_mode))
            {
                strcat(FileInfo,"dir\t");
                strcat(FileInfo,FileName);
            }
            else
            {
                strcat(FileInfo,"file\t");
                strcat(FileInfo,FileName);
            }

            write(sock,FileInfo,sizeof(FileInfo));
        }
    }

    closedir(PtrToDir);
}

void cd(int sock,char *DirName)
{
    DIR *PtrToDir;
    struct dirent *Pent;
    int FileCount=0;
    int i,Flag=0;

    PtrToDir=opendir(CurrentDirPath);
    Pent    =readdir(PtrToDir);

    while(Pent!=NULL)
    {
        FileCount++;
        Pent=readdir(PtrToDir);
    }

    closedir(PtrToDir);

    if(FileCount<=0)
    {
        return ;
    }
    else
    {
        PtrToDir=opendir(CurrentDirPath);

        for(i=0; i<FileCount; i++)
        {
            Pent=readdir(PtrToDir);

            if(strcmp(Pent->d_name,DirName)==0)
            {
                strcat(CurrentDirPath,"/");
                strcat(CurrentDirPath,DirName);
                Flag=1;
                break;
            }
        }

        if(Flag)
        {
            write(sock,CurrentDirPath,sizeof(CurrentDirPath));
        }

        closedir(PtrToDir);
    }

}

void cdback(int sock)
{
    int Length=strlen(CurrentDirPath);
    int i;

    for(i=Length-1; i>=0; i--)
    {
        if(CurrentDirPath[i]=='/')
        {
            CurrentDirPath[i]='\0';
            break;
        }

        CurrentDirPath[i]='\0';
    }

//    write(sock,CurrentDirPath,sizeof(CurrentDirPath));

}

void Help(int sock)
{
    int Length=strlen(help)+1;
    write(sock,help,Length);
}

void get(int sock,char *FileName)
{
    char FilePath[100];
    int fd;
    struct stat FileStat;
    long FileSize;
    char Buffer[BUFFER];

    memset(FilePath,0,sizeof(FilePath));
    strcpy(FilePath,CurrentDirPath);
    strcat(FilePath,"/");
    strcat(FilePath,FileName);

    fd=open(FilePath,O_RDONLY,S_IREAD);
    if(fd>0)
    {
        fstat(fd,&FileStat);
        FileSize=(long)FileStat.st_size;
        write(sock,&FileSize,sizeof(long));
        memset(Buffer,0,BUFFER);

        while(FileSize>BUFFER)
        {
            read(fd,Buffer,BUFFER);
            write(sock,Buffer,sizeof(Buffer));
            FileSize -=BUFFER;
        }

        read(fd,Buffer,FileSize);
        write(sock,&Buffer,FileSize);
        close(fd);
        printf("Transation Finished !");
    }
    else
    {
        perror("Open File Failed !\n");
    }
}

void put(int sock,char *FileName)
{
    char FilePath[100];
    int fd;
    char Buffer[BUFFER];
    long FileSize=0;

    memset(FilePath,0,sizeof(FilePath));
    strcpy(FilePath,FileName);
    strcat(FilePath,"/");
    strcat(FilePath,FileName);

    fd=open(FilePath,O_RDWR|O_CREAT,S_IREAD|S_IWRITE);
    if(fd>0)
    {
        memset(Buffer,0,BUFFER);
        read(sock,&FileSize,sizeof(long));

        while(FileSize>BUFFER)
        {
            read(sock,Buffer,BUFFER);
            write(fd,Buffer,BUFFER);
            FileSize-=BUFFER;
        }

        read(sock,Buffer,FileSize);
        write(fd,Buffer,FileSize);
        close(fd);
        printf("Transation complete !\n");
    }
    else
    {
        perror("Open File Failed !\n");
    }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自己写的ftp服务端程序代码,支持{"USER", do_user }, {"PASS", do_pass }, {"CWD", do_cwd }, {"XCWD", do_cwd }, {"CDUP", do_cdup }, {"REIN", do_rein },//重新初始化,此命令终止USER,重置所有参数,控制连接仍然打开,用户可以再次使用USER命令 {"QUIT", do_quit }, /*------------传输参数命令------------*/ {"PORT", do_port },//数据端口,主要向服务器发送客户数据连接的端口 //格式为PORT h1,h2,h3,h4,p1,p2,其中32位的IP地址用h1,h2,h3,h4表示,16位的TCP端口号用p1,p2表示 {"PASV", do_pasv },//此命令要求服务器数据传输进程在指定的数据端口侦听,进入被动接收请求的状态 {"TYPE", do_type },//文件类型,可指定ASCII码、EBCDIC码、Image、本地类型文件等参数 /*------------服务命令----------------*/ {"RETR", do_retr },//下载文件 {"STOR", do_stor },//上传 {"APPE", do_appe },//上传,如文件已存在,数据附加到尾部 {"REST", do_rest },//重新开始 {"RNFR", do_rnfr }, {"RNTO", do_rnto },//重命名文件或目录 {"ABOR", do_abor },//异常终止 {"DELE", do_dele },//删除文件 {"RMD", do_rmd },//删除目录 {"XRMD", do_rmd }, {"MKD", do_mkd },//新建目录 {"XMKD", do_mkd }, {"PWD", do_pwd },//打印当前目录 {"XPWD", do_pwd }, {"LIST", do_list },//列目录详细清单 {"NLST", do_nlst },//列目录短清单 {"SYST", do_syst },//获取系统信息 {"STAT", do_stat },//返回服务器状态 {"SIZE", do_size },//获得文件大小 {"HELP", do_help }, {"NOOP", do_noop }, {"SITE", do_site }, }等命令

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值