zoukankan      html  css  js  c++  java
  • socket编程FTP客户端demo

    这是计算机网络课程设计的作品,简单实现了FTP客户端。

    用winsock2头文件。算是socket编程的学习实践。

    所有代码在vc6.0下调试通过。

    /*
    *本程序参考rfc959标准。能与遵守此标准的服务器进行信息交互。仅限于windows系统。
    */
    #include < stdio.h >
    #include < string.h >
    #include < stdlib.h >/*system()*/
    #include < winsock2.h >
    #pragma comment(lib, "ws2_32.lib")
    #define ONUM 512
    #define MNUM 512
    #define FNUM 512
    #define ptstruct host {
        char ip[20];
        unsigned short port;
    };
    
    SOCKET ts;
    fd_set readfds;
    struct timeval timeval;
    struct host host;
    char renum[4];
    char ordertemp[ONUM];
    char order[ONUM];
    char ordercp[ONUM];
    char mess[MNUM];
    char file[FNUM];
    char setpath[FNUM];
    char setpathf[FNUM];
    int i, door, r, sys, seti;/*i for;door switch;r receive num;sys system state;set set state*/
    char * p;/*strtok*/
    int printmess();
    void input(char ordertemp[]);
    int ftp();
    int user();
    int pass();
    int command();
    int list();
    SOCKET createDataSocket();
    int set();
    int retr();
    int stor();
    
    int stor()
    {
        char filename[256];
        SOCKET ds;
        int wi;
        int r2, r3, r4, bsnum, brnum;
        FILE * fp = NULL;
        set();
        memset(filename, '\0', 256);
        memset(order, '\0', ONUM);
        for (i = 5; i <= 200 && ordercp[i] != '\0'; i++) {
            order[i - 5] = ordercp[i];
        }
        strcpy(filename, setpathf);
        strcat(filename, "\\\\");
        strcat(filename, order);
        memset(order, '\0', ONUM);
        strcpy(order, "type i\r\n");
        /*type i 二进制 type a ASCII*/
        send(ts, order, strlen(order), 0);
        switch (printmess())
        {
            case 421:
                closesocket(ts);
                sys = 0;
                return 421;
            case 530:
                closesocket(ts);
                sys = 0;
                return - 1;
            case 500:
            case 501:
            case 504:
            case 226:
                return - 1;
            case 200:
                break;
            default:
                return - 1;
        }
        ds = createDataSocket();
        if (ds ==- 1) {
            return - 1;
        }
        strcat(ordercp, "\r\n");
        send(ts, ordercp, strlen(ordercp), 0);
        switch (printmess())
        {
            case 421:
                closesocket(ds);
                closesocket(ts);
                sys = 0;
                return 421;
            case 532:
            case 530:
                closesocket(ds);
                closesocket(ts);
                sys = 0;
                return - 1;
            case 450:
            case 452:
            case 553:
            case 500:
            case 501:
                closesocket(ds);
                return - 1;
            case 125:
            case 150:
                break;
            default:
                closesocket(ds);
                return - 1;
        }
        fp = fopen(filename, "rb");
        if (!fp) {
            printf("read file fail!\n");
            closesocket(ds);
            return - 1;
        }
        r2 = 0;
        r3 = 0;
        r4 = 0;
        bsnum = 0;
        brnum = 0;
        wi = 1;
        while (wi)
        {
            memset(file, '\0', FNUM);
            r = fread(file, sizeof(char), FNUM, fp);
            if (r == 0) {
                closesocket(ds);
                wi = 0;
                break;
            }
            brnum = brnum + r;
            r3 = r;
            printf("read %8d bytes! have read %16d bytes!\r", r, brnum);
            do
            {
                r2 = send(ds, file, r3, 0);
                if (r2 == SOCKET_ERROR) {
                    printf("send file error!");
                    closesocket(ds);
                    return - 1;
                }
                bsnum = bsnum + r2;
                r3 = r3 - r2;
                printf("send %8d bytes! have sended %16d bytes!\r", r2, bsnum);
            }
            while (brnum > bsnum);
        }/*while*/
        printf("\n");
        switch (printmess())
        {
            case 425:
            case 426:
            case 451:
            case 551:
            case 552:
                closesocket(ds);
                fclose(fp);
                return - 1;
            case 250:
            case 226:
                fclose(fp);
                return 0;
            default:
                return 0;
        }
    }/*stor*/
    
    int retr()
    {
        char filename[256];
        unsigned long fsize, wfsize;
        int r2, wi;
        SOCKET ds;
        FILE * fp = NULL;
        memset(filename, '\0', 256);
        memset(order, '\0', ONUM);
        for (i = 5; i <= 200 && ordercp[i] != '\0'; i++) {
            order[i - 5] = ordercp[i];
        }
        strcpy(filename, setpathf);
        strcat(filename, "\\\\");
        strcat(filename, order);
        ds = createDataSocket();
        if (ds ==- 1) {
            return - 1;
        }
        memset(order, '\0', ONUM);
        strcpy(order, "type i\r\n");/*type i 二进制 type a ASCII*/
        send(ts, order, strlen(order), 0);
        switch (printmess())
        {
            case 421:
                closesocket(ds);
                closesocket(ts);
                sys = 0;
                return 421;
            case 530:
                closesocket(ds);
                closesocket(ts);
                sys = 0;
                return - 1;
            case 500:
            case 501:
            case 504:
            case 226:
                closesocket(ds);
                return - 1;
            case 200:
                break;
            default:
                closesocket(ds);
                return - 1;
        }
        strcat(ordercp, "\r\n");
        send(ts, ordercp, strlen(ordercp), 0);
        switch (printmess())
        {
            case 421:
                closesocket(ds);
                closesocket(ts);
                sys = 0;
                return 421;
            case 530:
                closesocket(ds);
                closesocket(ts);
                sys = 0;
                return - 1;
            case 450:
            case 500:
            case 501:
            case 550:
                closesocket(ds);
                return - 1;
            case 125:
            case 150:
                break;
            default:
                closesocket(ds);
                return - 1;
        }
        set();
        system(setpath);
        fp = fopen(filename, "wb");
        if (!fp) {
            printf("create file fail!\n");
            closesocket(ds);
            printmess();
            return - 1;
        }
        wi = 1;
        fsize = 0;
        wfsize = 0;
        while (wi)
        {
            memset(file, '\0', FNUM);
            r = recv(ds, file, FNUM, 0);
            if (r == SOCKET_ERROR) {
                printf("file recv error!\n");
                closesocket(ds);
                fclose(fp);
                return - 1;
            }
            fsize = fsize + r;
            if (r == 0) {
                wi = 0;
                break;
            }
            printf("receive %8d bytes! have received %16d bytes!\r", r, fsize);
            r2 = fwrite(file, sizeof(char), r, fp);
            // fflush(fp);/*这里是关键*/
            wfsize = wfsize + r2;
            printf("write %8d bytes!have written %20d bytes!\r", r2, wfsize);
        }/*while*/
        printf("\n");
        fflush(fp);/*这里是关键*/
        switch (printmess())
        {
            case 425:
            case 426:
            case 451:
                closesocket(ds);
                fclose(fp);
                return - 1;
            case 250:
            case 226:
                closesocket(ds);
                wi = 1;
                while (wi) {
                    if (fclose(fp) == 0) {
                        wi = 0;
                    }
                    return 0;
                    default:
                    closesocket(ds);
                    fclose(fp);
                    return 0;;
                }
        }
    }/*retr()*/
    
    int set()
    {
        int n, m;
        n = 3;
        m = 0;
        if (strcmp(order, "set") != 0 && seti == 1) {
            return 1;
        }
        else if (strcmp(order, "set") != 0 && seti == 0)
        {
            memset(setpath, '\0', FNUM);
            memset(setpathf, '\0', FNUM);
            strcpy(setpath, "md d:\\rhFTPdir");
            strcpy(setpathf, "d:\\\\rhFTPdir");
            return 2;
        }
        memset(setpath, '\0', FNUM);
        memset(setpathf, '\0', FNUM);
        memset(order, '\0', ONUM);
        if (ordercp[5] != ':') {
            printf("error input!\n");
            return - 1;
        }
        for (i = 4; i <= 200 && ordercp[i] != '\0'; i++) {
            order[i - 4] = ordercp[i];
        }
        strcpy(setpath, "md ");
        for (i = 0; i <= FNUM - 5 && order[i] != '\0'; i++)
        {
            if (order[i] == '\\') {
                strcat(setpath, "\\\\");
                n++;
                strcat(setpathf, "\\\\");
                m++;
                continue;
            }
            setpathf[i + m] = order[i];
            setpath[i + n] = order[i];
        }
        printf("setpath %s\n", setpath);
        seti = 1;
        return 0;
    }/*set*/
    
    int list()
    {
        SOCKET ds;
        int wi;
        ds = createDataSocket();
        if (ds ==- 1) {
            return - 1;
        }
        strcat(ordercp, "\r\n");
        send(ts, ordercp, strlen(ordercp), 0);
        switch (printmess())
        {
            case 421:
                closesocket(ds);
                closesocket(ts);
                sys = 0;
                return 421;
            case 530:
                closesocket(ds);
                closesocket(ts);
                sys = 0;
                return - 1;
            case 450:
            case 500:
            case 501:
            case 502:
                closesocket(ds);
                return - 1;
            case 125:
            case 150:
                break;
            default:
                closesocket(ds);
                return - 1;
        }
        wi = 1;
        while (wi)
        {
            memset(file, '\0', FNUM);
            r = recv(ds, file, FNUM - 1, 0);
            if (r == SOCKET_ERROR) {
                printf("list file recv error!\n");
                closesocket(ds);
                return - 1;
            }
            printf("%s", file);
            if (r == 0) {
                wi = 0;
            }
        }
        switch (printmess())
        {
            case 425:
            case 426:
            case 451:
            case 226:
            case 250:
                closesocket(ds);
                return 0;
            default:
                closesocket(ds);
                return - 1;
        }
    }/*list*/
    
    SOCKET createDataSocket()
    {
        char p1[5], p2[5];
        unsigned short port;
        int p1s, p2s;
        SOCKET ds;
        struct sockaddr_in server;
        memset(order, '\0', ONUM);
        /*pasv*/
        strcpy(order, "pasv\r\n");
        send(ts, order, strlen(order), 0);
        r = printmess();
        if (r ==- 1 || r != 227) {
            return - 1;
        }
        memset(p1, '\0', 5);
        memset(p2, '\0', 5);
        p1s = 0;
        p2s = 0;
        for (i = 0, r = 0; i < 200 && mess[i] != '\0'; i++)
        {
            if (mess[i] == ',') {
                r++;
                continue;
            }
            if (r == 4) {
                p1[p1s] = mess[i];
                p1s++;
                continue;
            }
            if (r == 5) {
                p2[p2s] = mess[i];
                p2s++;
                continue;
            }
        }
        port = atoi(p1) * 256 + atoi(p2);
        printf("port:%d\n", port);
        server.sin_family = AF_INET;
        server.sin_port = htons(port);
        server.sin_addr.S_un.S_addr = inet_addr(host.ip);
        ds = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        /*TCP*/
        if (ds ==- 1) {
            printf("Failed socket() in createDataSocket()\n");
            return - 1;
        }
        r = connect(ds, (struct sockaddr * ) & server, sizeof(server));
        if (r == SOCKET_ERROR) {
            printf("connect error in createDataSocket()!\n");
            closesocket(ds);
            return - 1;
        }
        return ds;
    }/*createDataSocket()*/
    
    int command()
    {
        strcat(ordercp, "\r\n");
        send(ts, ordercp, strlen(ordercp), 0);
        switch (printmess())
        {
            case 421:
                closesocket(ts);
                sys = 0;
                return 421;
            case 221:
                closesocket(ts);
                sys = 0;
                return 221;
            case 530:
                closesocket(ts);
                sys = 0;
                return 0;
            case 200:
            case 250:
            case 450:
            case 550:
            case 500:
            case 501:
            case 502:
                return 0;
            default:
                return - 1;
        }
    }/*command*/
    
    int pass()
    {
        strcat(ordercp, "\r\n");
        send(ts, ordercp, strlen(ordercp), 0);
        switch (printmess())
        {
            case 421:
                closesocket(ts);
                sys = 0;
                return 421;
            case 530:
                closesocket(ts);
                sys = 0;
                return 0;
            case 500:
            case 501:
            case 503:
            case 202:
                return 0;
            case 332:
                sys = 1;
                return 0;
            case 230:
                sys = 3;
                return 0;
            default:
                return - 1;
        }
    }/*pass*/
    
    int user()
    {
        if (ordercp[5] == '-') {
            strcat(order, " anonymous\r\n");
            send(ts, order, strlen(order), 0);
        }
        else {
            strcat(ordercp, "\r\n");
            send(ts, ordercp, strlen(ordercp), 0);
        }
        switch (printmess())
        {
            case 421:
                closesocket(ts);
                sys = 0;
                return 421;
            case 530:
                closesocket(ts);
                sys = 0;
                return 0;
            case 230:
                sys = 3;
                return 0;
            case 500:
            case 501:
            case 332:
                return 0;
            case 331:
                sys = 2;
                return 0;
            default:
                return - 1;
        }
    }/*user*/
    
    int ftp()
    {
        WSADATA wsaData;
        struct sockaddr_in serveraddr;
        if (sys != 0) {
            printf("please bye first!\n");
            return 0;
        }
        WSAStartup(MAKEWORD(2, 2), & wsaData);
        /*建立与Socket库绑定*/
        ts = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        /*TCP*/
        if (ts ==- 1) {
            printf("Failed socket()\n");
            WSACleanup();
            return - 1;
        }
        memset(host.ip, '\0', 20);
        p = strtok(NULL, " ");
        strcpy(host.ip, p);
        p = strtok(NULL, " ");
        if (p == NULL) {
            host.port = 21;
        }
        else {
            host.port = atoi(p);
        }
        serveraddr.sin_family = AF_INET;
        /*主机地址标识*/
        serveraddr.sin_port = htons(host.port);
        /*port htons 16*/
        serveraddr.sin_addr.S_un.S_addr = inet_addr(host.ip);
        /*ip*/
        r = connect(ts, (struct sockaddr * ) & serveraddr, sizeof(serveraddr));
        /*发送连接请求*/
        if (r == SOCKET_ERROR) {
            printf("connect error!\n");
            return - 1;
        }
        switch (printmess())
        {
            case 220:
                sys = 1;
                return 0;
            case 120:
                while (printmess() == 220) {
                    sys = 1;
                    return 0;
                }
            case 421:
                closesocket(ts);
                sys = 0;
                return 421;
            case - 1:
                return - 1;
            default:
                return - 1;
        }
    }/*ftp*/
    
    int printmess()
    {
        int p, n, wi;
        p = 0;
        n = 0;
        wi = 1;
        memset(renum, '\0', 4);
        FD_ZERO(&readfds);
        /*select*/
        FD_SET(ts, & readfds);
        r = select(0, & readfds, NULL, NULL, & timeval);
        while (r > 0 && FD_ISSET(ts, & readfds) && wi == 1)
        {
            memset(mess, '\0', MNUM);
            r = recv(ts, mess, MNUM - 1, 0);
            if (r == SOCKET_ERROR) {
                printf("printmess recv error!\n");
                return - 1;
            }
            if (p == 0) {
                strncpy(renum, mess, 4);
                n = atoi(renum);
                p = 1;
            }
            printf("%s", mess);
            FD_ZERO(&readfds);
            /*select*/
            FD_SET(ts, & readfds);
            r = select(0, & readfds, NULL, NULL, & timeval);
            if (r == 0) {
                wi = 0;
            }
        }
        return n;
    }/*printmess()*/
    
    void input(char ordertemp[])
    {
        for (i = 0; i < ONUM; i++) {
            ordertemp[i] = getchar();
            if (ordertemp[i] == 10) {
                ordertemp[i] = '\0';
                break;
            }
            /*10 enter*/
        }
        if (ordertemp[0] != '\0')
        {
            strcpy(ordercp, ordertemp);
            p = NULL;
            p = strtok(ordertemp, " ");
            strcpy(order, p);
            strlwr(order);
        }
    }/*input*/
    
    int main()
    {
        int wi;
        seti = 0;
        timeval.tv_sec = 0;
        /*5000ms 避免死锁*/
        timeval.tv_usec = 500000;
        printf("** Welcome to use RedHaw FTPclient! **\n");
        sys = 0;
        /*0-初始 1-接收user 2-接收pass 3-接收其他command*/
        wi = 1;
        while (wi)
        {
            memset(ordertemp, '\0', ONUM);
            memset(order, '\0', ONUM);
            memset(ordercp, '\0', ONUM);
            switch (sys)
            {
                case 0:
                    printf("+ ftp <host-ip> [port] + exit +\n");
                    break;
                case 1:
                    printf("+ user <username> Tip:\" \'-\' for anonymous \" +\n");
                    break;
                case 2:
                    printf("+ pass <password> Tip:\" \'-\' for anonymous \" +\n");
                    break;
                default:
                    printf("+ help|list|cdup|cwd <dir>|mkd <>|rmd <>|set <dir> +\n");
                    printf("+ user|quit|exit|retr <down>|stor <up>|dele <file> +\n");
            }
            printf("rhFTP>");
            input(ordertemp);
            if (ordertemp[0] == '\0') {
                continue;
            }
            if (strcmp(order, "ftp") == 0 && sys == 0) {
                door = 1;
            }
            /*1 ftp */
            else if (strcmp(order, "user") == 0 && (sys == 1 || sys == 3)) door = 2;
            /*2 user*/
            else if (strcmp(order, "pass") == 0 && sys == 2) door = 3;
            /*3 pass*/
            else if (strcmp(order, "quit") == 0 && sys == 3) door = 4;
            /*4 quit*/
            else if (strcmp(order, "exit") == 0 && (sys == 0 || sys == 3)) door = 5;
            /*5 exit*/
            else if (strcmp(order, "list") == 0 && sys == 3) door = 6;
            /*6 list*/
            else if (strcmp(order, "cwd") == 0 && sys == 3) door = 7;
            /*7 cwd */
            else if (strcmp(order, "dele") == 0 && sys == 3) door = 8;
            /*8 dele*/
            else if (strcmp(order, "retr") == 0 && sys == 3) door = 9;
            /*9 retr*/
            else if (strcmp(order, "set") == 0 && sys == 3) door = 10;
            /*10 set */
            else if (strcmp(order, "stor") == 0 && sys == 3) door = 11;
            /*11 stor*/
            else if (strcmp(order, "cdup") == 0 && sys == 3) door = 12;
            /*12 cdup*/
            else if (strcmp(order, "help") == 0 && sys == 3) door = 13;
            /*13 help*/
            else if (strcmp(order, "mkd") == 0 && sys == 3) door = 14;
            /*14 mkd */
            else if (strcmp(order, "rmd") == 0 && sys == 3) door = 15;
            /*15 rmd */
            else door = 0;
            switch (door)
            {
                case 0:
                    printf("Disallowed command!\n");
                    break;
                case 1:
                    r = ftp();
                    break;
                case 2:
                    r = user();
                    break;
                case 3:
                    r = pass();
                    break;
                case 4:
                    r = command();
                    break;
                case 5:
                    if (sys == 3) {
                        memset(ordercp, '\0', ONUM);
                        strcpy(ordercp, "quit\r\n");
                        command();
                        closesocket(ts);
                    }
                    wi = 0;
                    break;
                case 13:
                case 6:
                    r = list();
                    break;
                case 12:
                case 14:
                case 15:
                case 7:
                case 8:
                    r = command();
                    break;
                case 9:
                    r = retr();
                    break;
                case 10:
                    r = set();
                    break;
                case 11:
                    r = stor();
                    break;
                default:
                    wi = 0;
                    break;
            }
            /*switch(door)*/
        }
        /*while(wi)*/
        WSACleanup();
        return 0;
    }
    /*main*/

    - by 一个农夫 -

  • 相关阅读:
    Python实战之SocketServer模块
    CentOS出错You don't have permission to access on this server
    系统瓶颈分析
    loadrunner支持https协议的操作方法-经验总结
    Loadrunner上传与下载文件脚本
    Loadrunner之HTTP接口测试脚本实例
    Android界面性能调优手册
    Loadrunner11.0 录制手机App脚本的方法
    资源监控工具--spotlight
    Jmeter常见问题
  • 原文地址:https://www.cnblogs.com/afarmer/p/1610944.html
Copyright © 2011-2022 走看看