socket編程FTP用戶端demo

來源:互聯網
上載者:User

這是電腦網路課程設計的作品,簡單實現了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 一個農夫 -

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.