ftp服务器的简单实现(一)——服务器端

服务器端的代码:

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

#define TRUE 1
#define LISTEN_PORT 3499
#define dataLen 1024

char currentDirPath[200];
char currentDirName[30];
char help[]={"get   get a file from server\n"
            "put upload a file to server\n"
            "pwd display 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 cmd_pwd(int sock);
void cmd_dir(int sock);
void cmd_cd(int sock, char *dirName);
void cmd_cdback(int sock);
void cmd_help(int sock);
void cmd_get(int sock, char *fileName);
void cmd_put(int sock, char *fileName);

int main(int argc, char *argv[])
{
    int sock, sockmsg, length, lengthmsg;
    char client_cmd[10], cmd_arg[20];
    struct sockaddr_in server;
    struct sockaddr_in servermsg;
    int datasock, msgsock;
    pid_t child;

    //int datasock;  //data socket
    int rval;
    sock = socket(AF_INET, SOCK_STREAM, 0);
    sockmsg = socket(AF_INET, SOCK_STREAM, 0);

    if(sock < 0 || sockmsg < 0)
    {
        perror("opeing stream socket");
        exit(0);
    }

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

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

    if(bind(sock, (struct sockaddr *)&server, sizeof(server)) <0
       || bind(sockmsg, (struct sockaddr*)&servermsg, sizeof(servermsg))<0 )
    {
        perror("binding stream socket");
        exit(1);
    }

    length = sizeof(server);
    lengthmsg = sizeof(servermsg);
    if(getsockname(sock, (struct sockaddr *)&server, &length) < 0 ||
        getsockname(sockmsg, (struct sockaddr *)&servermsg, &lengthmsg) < 0)
    {
        perror("getting socket name");
        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
    {
        datasock = accept(sock, (struct sockaddr *)0, (int *)0);
        msgsock = accept(sockmsg, (struct sockaddr*)0, (int *)0);
        if(-1 == datasock || -1 == msgsock)
        {
            perror("accept");
        }
        else
        {
            if(-1 == (child = fork()))
            {
                printf("Fork Error!\n");
            }
            //The child process
            if(0 == child)
            {
                printf("connection accepted! new client comming\n");
loop:
                memset(client_cmd, 0, sizeof(client_cmd));
                rval = 0;
                rval = read(msgsock, client_cmd, sizeof(client_cmd));

                if(rval < 0)
                {
                    perror("reading command failed\n");
                }
                else if(0 == rval)
                {
                    printf("connection closed.\n");
                    close(datasock);
                    close(msgsock);
                }
                else
                {
                    if(strcmp(client_cmd, "pwd") == 0)
                    {
                        printf("command pwd\n");
                        cmd_pwd(datasock);
                        printf("done\n\n");
                        goto loop;
                    }
                    else if(strcmp(client_cmd, "dir") == 0)
                    {
                        printf("command dir\n");
                        cmd_dir(datasock);
                        printf("\n\n");
                        goto loop;
                    }
                    else if(strcmp(client_cmd, "cd") == 0)
                    {
                        printf("command cd\n");
                        memset(cmd_arg, 0, sizeof(cmd_arg));
                        read(msgsock, cmd_arg, sizeof(cmd_arg));
                        cmd_cd(datasock, cmd_arg);
                        printf("done\n\n");
                        goto loop;
                    }
                    else if(strcmp(client_cmd, "cd..") == 0)
                    {
                        printf("command cd..\n");
                        cmd_cdback(datasock);
                        printf("done\n\n");
                        goto loop;
                    }

                    else if(strcmp(client_cmd, "get") == 0)
                    {
                        printf("command get\n");
                        memset(cmd_arg, 0, sizeof(cmd_arg));
                        read(msgsock, cmd_arg, sizeof(cmd_arg));
                        cmd_get(datasock, cmd_arg);
                        printf("done\n\n");
                        goto loop;
                    }
                    else if(strcmp(client_cmd, "put") == 0)
                    {
                        printf("command get\n");
                        memset(cmd_arg, 0, sizeof(cmd_arg));
                        read(msgsock, cmd_arg, sizeof(cmd_arg));
                        cmd_put(datasock, cmd_arg);
                        printf("done\n\n");
                        goto loop;
                    }
                    else if(strcmp(client_cmd, "?") == 0)
                    {
                        printf("command ?\n");
                        cmd_help(datasock);
                        printf("done\n\n");
                        goto loop;
                    }
                    else if(strcmp(client_cmd, "quit") == 0)
                    {
                        printf("quit\n");
                        goto endchild;
                    }
                    else
                    {
                        printf("bad request\n");
                        goto loop;
                    }
                }
endchild:
                printf("connection closed.\n");
                close(datasock);
                close(msgsock);
                exit(0);
            }

        }
    }while(TRUE);

    exit(0);
}

//pwd command
void cmd_pwd(int sock)
{
    int len;
    memset(currentDirPath, 0, sizeof(currentDirPath));
    getcwd(currentDirPath, sizeof(currentDirPath));
    char *savePointer = getDirName(currentDirPath);
    printf("currentDirPath is %s", currentDirPath);
    strcpy(currentDirName, savePointer);

    printf("currentDirName is %s\n", currentDirName);
    len = strlen(currentDirName)+1;
    printf("len is %d\n", len);
    write(sock, currentDirName, len);
}

//dir command
void cmd_dir(int sock)
{
    DIR *pdir;
    char fileName[30];
    char fileInfo[50];
    int i, fcounts = 0, len;
    struct dirent *pent;
    int fd;
    struct stat fileSta;
    char filePath[200];

    pdir = opendir(currentDirPath);
    pent = readdir(pdir);

    while(pent!=NULL)
    {
        fcounts++;
        pent = readdir(pdir);
    }

    write(sock, &fcounts, sizeof(int));
    closedir(pdir);

    if(fcounts <= 0)
    {
        return;
    }
    else
    {
        pdir = opendir(currentDirPath);
        for(i=0; i<fcounts; i++)
        {
            pent = readdir(pdir);
            memset(fileName, 0, 30);
            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, &fileSta);
            if(S_ISDIR(fileSta.st_mode))
            {
                strcat(fileInfo, "dir\t");
                strcat(fileInfo, fileName);
            }
            else
            {
                strcat(fileInfo, "file\t");
                strcat(fileInfo, fileName);
            }
            write(sock, fileInfo, sizeof(fileInfo));
        }
        closedir(pdir);
    }
}

void cmd_cd(int sock, char *dirName)
{
    DIR *pdir;
    struct dirent *pent;
    char filename[30];
    int i,fcounts = 0;
    int flag = 0;

    pdir = opendir(currentDirPath);
    pent = readdir(pdir);

    printf("currentDirPath is %s\n", currentDirPath);
    while(pent != NULL)
    {
        fcounts++;
        pent = readdir(pdir);
    }

    closedir(pdir);
    if(fcounts <= 0)
    {
        return;
    }
    else
    {
        pdir = opendir(currentDirPath);
        for(i=0; i<fcounts; i++)
        {
            pent = readdir(pdir);
            if(strcmp(pent->d_name, dirName) == 0)
            {
                strcat(currentDirPath, "/");
                strcat(currentDirPath, dirName);
                flag = 1;
                break;
            }
        }

        if(flag == 1)
        {
            write(sock, currentDirPath, sizeof(currentDirPath));
        }
        closedir(pdir);
    }
}

//command cd..
void cmd_cdback(int sock)
{
    int len;
    int i, record;

    len = strlen(currentDirPath);

    for(i=len-1; i>=0; i--)
    {
        if(currentDirPath[i] == ‘/‘)
        {
            currentDirPath[i] = ‘\0‘;
            break;
        }
        currentDirPath[i] = ‘\0‘;
    }
}

//command ?
void cmd_help(int sock)
{
    int len = strlen(help)+1;
    write(sock, help, len);
}

//command get
void cmd_get(int sock, char* fileName)
{
    int fd;
    struct stat fileSta;
    long fileSize;
    char filePath[200], buf[dataLen];

    memset(filePath, 0, sizeof(filePath));
    strcpy(filePath, currentDirPath);
    strcat(filePath, "/");
    strcat(filePath, fileName);

    fd = open(filePath, O_RDONLY, S_IREAD);
    if(fd != -1)
    {
        fstat(fd, &fileSta);
        fileSize = (long)fileSta.st_size;
        write(sock, &fileSize, sizeof(long));
        memset(buf, 0, dataLen);
        while(fileSize > dataLen)
        {
            read(fd, buf, dataLen);
            write(sock, buf, dataLen);
            fileSize = fileSize - dataLen;
        }

        read(fd, buf, fileSize);
        write(sock, buf, fileSize);
        close(fd);
        printf("transfer completed\n");
    }
    else
    {
        printf("open file %s failed\n", filePath);
    }
}

//command put
void cmd_put(int sock, char *fileName)
{
    int fd;
    long fileSize;

    char filePath[200], buf[dataLen];
    strcpy(filePath, currentDirPath);
    strcat(filePath, "/");
    strcat(filePath, fileName);

    fd = open(filePath, O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
    if(fd != -1)
    {
        memset(buf, 0, dataLen);
        read(sock, &fileSize, sizeof(long));

        while(fileSize > dataLen)
        {
            read(sock, buf, dataLen);
            write(fd, buf, dataLen);
            fileSize = fileSize - dataLen;
        }

        read(sock, buf, fileSize);
        write(fd, buf, fileSize);

        close(fd);
        printf("transfer completed\n");
    }
    else
    {
        printf("open file %s failed\n", filePath);
    }
}

//get the last string afer the last cha ‘/‘
char *getDirName(char *dirPathName)
{
    int i, pos, len;
    char *dirName;

    if(dirPathName == NULL)
    {
        printf("directory absoultly path is null\n");
        return NULL;
    }

    len = strlen(dirPathName);
    for(i=len-1; i>=0; i--)
    {
        if(dirPathName[i] == ‘/‘)
        {
            pos = i;
            break;
        }
    }

    dirName = (char *)malloc(len-pos+1);
    for(i=pos+1; i<len; i++)
    {
        printf("%c",dirPathName[i]);
        dirName[i-pos-1] = dirPathName[i];
    }

    return dirName;
}

用gcc -o server server.c

如果加上调试信息就是gcc -g -o server server.c

时间: 2024-10-14 11:39:44

ftp服务器的简单实现(一)——服务器端的相关文章

ftp服务器的简单配置使用

yum install -y vsftpd systemctl start vsftpd cd /var/ftp/pub/ mkdir 111 touch weifeng.txt 打开 ftp://服务器ip/pub 里面有文件 111 和 weifeng.txt

ftp服务器的简单实现(二)——客户端

客户端: #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/stat.h> #include <fcntl.h> #inclu

Android中FTP服务器搭建入门

ftp服务器简单介绍:FTP(File Transfer Protocol)是文件传输协议的简称. 作用:让用户连接上一个远程计算机(该计算机上运行着FTP服务器程序)察看远程计算机有哪些文件,然后把文件从远程计算机上拷到本地计算机,或把本地计算机的文件送到远程计算机去. Apache 官网ftpserver有详细介绍和使用说明以及必要文件下载:http://mina.apache.org/ftpserver-project/embedding_ftpserver.html 首先要阅读官网上的介

CentOS7 搭建 FTP 服务器

经常需要把 window 下的文件传到 Linux 中, 搭建一个简单的 ftp 服务器, 简单使用,性价比高, 棒! 安装 vdftpd -----: yum -y install vsftpd 新建登录 ftp 服务器的账号: 新建用户: useradd ftp1 修改用户密码: passwd 123 开启 vsftpd 服务: systemctl start vsftpd.service 关闭 vsftpd 服务: systemctl stop vsftpd.service 设置 SELi

Python一秒搭建ftp服务器,帮助你在局域网共享文件【华为云技术分享】

“老板 来碗面” “要啥面?” “内牛满面..” 最近项目上的事情弄得人心累,本来是帮着兄弟项目写套入口代码,搞着搞着就被拉着入坑了.搞开发的都知道,最怕弄这种项目portal的东西,你调用一堆东西,结果各种调用报错都反馈到你这里,导致的结果就是除了啥问题都找你. 最形象的比喻就是,眼前一栋楼,你是看门的.电梯坏了找你.住户被盗了找你.连谁家下水不通了也找你,各种无厘头的破事儿,我就想送出一张图… 共享文件 熟悉Python的朋友们都知道,python自带了一个Simple HTTP Serve

ftp服务器和http服务器的简单安装测试

0.[ 安装前的准备工作:] 1)chkconfig iptables off或service iptables stop 禁防火墙(centos6) systemctl  disable firewalld.service 或systemctl  stop firewalld.services(centos7) 2)关闭selinux vim /etc/selinux/config 中selinux=permisssive setenforce   0 getenforce 验证是否有效 3)

搭建简单FTP服务器以及过程中容易遇到的几个问题(一)

FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制文件的双向传输.同时,它也是一个应用程序(Application). FTP的服务器软件有很多下面就拿vsftpd举例. vsftpd 是一款在Linux发行版本里面最主流的FTP服务器程序,特点是小巧轻快,安全易用 下面开始安装 先检测是否存在vsftp服务 [[email protected] ~]# rpm -qa |grep vsftpd 没有

使用Python或Node创建简单web服务器和FTP服务器实现文件共享

有时我们需要给旁边的人传一些文件,如果大家都用windows或者mac,那么皆大欢喜,直接用QQ传就可以了,但如果有个不省心的家伙用linux怎么办?可以用网盘或者U盘,或者另外一种更酷一些的方法来实现文件共享. 使用Python(2.6-2.7)创建简单的web服务器 进入某目录,执行 python -m SimpleHTTPServer port 即可创建一个局域网内可用的web服务器.使用ip:port进行访问. 使用Node创建简单的web服务器 首先执行一下命令安装http-serve

4步win7下简单FTP服务器搭建(试验成功)

本文介绍通过win7自带的IIS来搭建一个只能实现基本功能的FTP服务器,第一次装好WIN7后我愣是没整出来,后来查了一下网上资料经过试验后搭建成功,其实原理和步骤与windows前期的版本差不多,主要是对新的操作系统还不是很熟悉.相信用过WIN7一段时间的都能独立解决掉.      主要分为4个步骤     1.安装FTP服务     2.在IIS控制面板里添加FTP站点     3.配置FTP站点 4. 测试站点是否正常工作   ftp://192.168.10.13