zoukankan      html  css  js  c++  java
  • 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
    "    
                "put upload a file to server
    "
                "pwd display the current directory of server
    "
                "cd change the directory of server
    "
                "?   display the whole command which equals 'help'
    "
                "quit   return 
    "};
    
    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
    ", 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!
    ");
                }
                //The child process
                if(0 == child)
                {
                    printf("connection accepted! new client comming
    ");
    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
    ");
                    }
                    else if(0 == rval)
                    {
                        printf("connection closed.
    ");
                        close(datasock);
                        close(msgsock);
                    }
                    else
                    {
                        if(strcmp(client_cmd, "pwd") == 0)
                        {
                            printf("command pwd
    ");
                            cmd_pwd(datasock);
                            printf("done
    
    ");
                            goto loop;
                        }
                        else if(strcmp(client_cmd, "dir") == 0)
                        {
                            printf("command dir
    ");
                            cmd_dir(datasock);
                            printf("
    
    ");
                            goto loop;
                        }
                        else if(strcmp(client_cmd, "cd") == 0)
                        {
                            printf("command cd
    ");
                            memset(cmd_arg, 0, sizeof(cmd_arg));
                            read(msgsock, cmd_arg, sizeof(cmd_arg));
                            cmd_cd(datasock, cmd_arg);
                            printf("done
    
    ");
                            goto loop;
                        }
                        else if(strcmp(client_cmd, "cd..") == 0)
                        {
                            printf("command cd..
    ");
                            cmd_cdback(datasock);
                            printf("done
    
    ");
                            goto loop;
                        }
                        
                        else if(strcmp(client_cmd, "get") == 0)
                        {
                            printf("command get
    ");
                            memset(cmd_arg, 0, sizeof(cmd_arg));
                            read(msgsock, cmd_arg, sizeof(cmd_arg));
                            cmd_get(datasock, cmd_arg);
                            printf("done
    
    ");
                            goto loop;
                        }
                        else if(strcmp(client_cmd, "put") == 0)
                        {
                            printf("command get
    ");
                            memset(cmd_arg, 0, sizeof(cmd_arg));
                            read(msgsock, cmd_arg, sizeof(cmd_arg));
                            cmd_put(datasock, cmd_arg);
                            printf("done
    
    ");
                            goto loop;
                        }
                        else if(strcmp(client_cmd, "?") == 0)
                        {
                            printf("command ?
    ");
                            cmd_help(datasock);
                            printf("done
    
    ");
                            goto loop;
                        }
                        else if(strcmp(client_cmd, "quit") == 0)
                        {
                            printf("quit
    ");
                            goto endchild;
                        }
                        else
                        {
                            printf("bad request
    ");
                            goto loop;
                        }
                    }
    endchild:
                    printf("connection closed.
    ");
                    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
    ", currentDirName);
        len = strlen(currentDirName)+1;
        printf("len is %d
    ", 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	");
                    strcat(fileInfo, fileName);
                }
                else
                {
                    strcat(fileInfo, "file	");
                    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
    ", 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] = '';
                break;
            }
            currentDirPath[i] = '';
        }
    }
    
    //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
    ");
        }
        else
        {
            printf("open file %s failed
    ", 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
    ");
        }
        else
        {
            printf("open file %s failed
    ", 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
    ");
            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

  • 相关阅读:
    什么是RUP
    oracle 导入导出
    jsp 标签
    java json 交互
    Spring MVC 学习过程遇到的问题
    Spring 与其他ORM 框架结合 作数据持久层解析 (转)
    Spring mvc 中快速获取request、reponse、session
    Spring 数据绑定
    spring mvc 请求对应控制器的解析策略配置
    spring 的几种注解
  • 原文地址:https://www.cnblogs.com/hpcpp/p/7097904.html
Copyright © 2011-2022 走看看