FTP上傳的實現

對於文件的讀寫不太熟悉,犯了很多錯誤。服務器

好比,對於傳送的文件中有各類文件,剛開始時用的r打開,只能實現txt文件的傳輸,而且傳輸後獲得的文件的格式與源文件不一致。還有對於fgets與fread不太瞭解。併發


  • fget:tcp

函數原型:char *fgets(char *string, int n, FILE *fp);ide

頭文件:#include<stdio.h>函數

是不是標準函數:是測試

函數功能:從fp所指的文件中讀取一個長度爲(n-1)的字符串,並將該字符串存入以string爲起始地址的緩衝區中。fgets函數有三個參數,其中string爲緩衝區首地址,n規定了要讀取的最大長度,fp爲文件指針。ui

返回值:返回地址string,若遇到文件結束符或出錯,返回NULL。用feof ferror判斷是否出錯。spa


  • fread:指針

函數原型:int fread(void *buf, int size, int count, FILE *fp);調試

頭文件:#include<stdio.h>

是不是標準函數:是

函數功能:從fp指向的文件中讀取長度爲size count個數據項,並將它輸入到以buf爲首地址的緩衝區中。此時,文件指針fp會自動增長實際讀入數據的字節數,即fp指向最後讀入字符的下一個字符位置。

返回值:返回實際讀入數據項的個數,即count值。若遇到錯誤或文件結束返回0


  • fwrite:

函數原型:int fwrite(void *buf, int size, int count, FILE *fp);

頭文件:#include<stdio.h>

是不是標準函數:是

函數功能:將buf所指向的count*size個字節的數據輸出到文件指針fp所指向的文件中去。該函數與fread相對,輸出數據後,文件指針fp自動指向輸出的最後一個字符的下一個位置。該函數經常使用於分批將數據塊輸出到文件中。

返回值:返回實際寫入文件數據項個數。




在個人使用過程當中感覺是對獲取的字符串處理則用fgets,連續讀取文件則使用fread。



#include "sock_class.h"
#define  RESPONSE_BUF_SIZE  4096
#define  DATA_BUF_SIZE      4096
int FtpPut(const char* szIP, const char* szPath, const char* szFile);
int main(int argc, char *argv[])
{
    char szData[4096];
    if (argc < 4)
    {
        printf("USAGE: %s IP Path File", argv[0]);
        return 1;
    }
    if (WinSockInit() != 0)
    {
        printf("WSAStartup failed with error \n");
        return 1;
    }
    int nRet = FtpPut(argv[1], argv[2], argv[3]);
                                                                                                                                                                          
    WSACleanup();
    return nRet;
}
//處理響應信息
int GetFtpReponse(tcp_sock& sockCtrl, char* szRespBuf, int nLen)
{
    int nRetCode;
    if (sockCtrl.read_line(szRespBuf, nLen) == SOCKET_ERROR)
    {
        printf("GetFtpReponse error!\n");
        return 0;
    }
    printf(szRespBuf);
    if (sscanf(szRespBuf, "%ld", &nRetCode) != 1)
    {
        printf("GetFtpReponse error(%s)!\n", szRespBuf);
        return 0;
    }
    if (szRespBuf[3] == '-')
    {
        do
        {
            if (sockCtrl.read_line(szRespBuf, nLen) == SOCKET_ERROR)
            {
                printf("GetFtpReponse error!\n");
                return 0;
            }
            if ((szRespBuf[0] >= '0') && (szRespBuf[0] <= '9'))
            {
                break;
            }
        }
        while (1);
    }
                                                                                                                                                                           
    return nRetCode;
}
//發控制信息
int SendFtpCmd(tcp_sock& sockCtrl, const char* szCmd)
{
    if (sockCtrl.write_line(szCmd, strlen(szCmd)) == SOCKET_ERROR)
    {
        printf("SendFtpCmd error(%s)!\n", szCmd);
        return 0;
    }
    return 1;
}
//鏈接Ftp服務器
int ConnectFtp(tcp_sock& sockCtrl, const char* szIP)
{
    char    szRespBuf[RESPONSE_BUF_SIZE + 1];
    if (!sockCtrl.connect(szIP, "21"))
    {
        printf("connect error!\n");
        return 1;
    }
                                                                                                                                                                           
    if (GetFtpReponse(sockCtrl, szRespBuf, RESPONSE_BUF_SIZE) != 220)
    {
        printf("GetFtpReponse 220 error!\n");
        return 1;
    }
    return 0;
}
//登錄Ftp服務器
int LoginFtp(tcp_sock& sockCtrl)
{
    char    szRespBuf[RESPONSE_BUF_SIZE + 1];
    //User Name
    if (!SendFtpCmd(sockCtrl, "USER Anonymous"))
    {
        printf("SendFtpCmd error!\n");
        return 1;
    }
    if (GetFtpReponse(sockCtrl, szRespBuf, RESPONSE_BUF_SIZE) != 331)
    {
        printf("GetFtpReponse 331 error!\n");
        return 1;
    }
    //Pass
    if (!SendFtpCmd(sockCtrl, "PASS asdfa@sina.com"))
    {
        printf("SendFtpCmd error!\n");
        return 1;
    }
    if (GetFtpReponse(sockCtrl, szRespBuf, RESPONSE_BUF_SIZE) != 230)
    {
        printf("GetFtpReponse 230 error!\n");
        return 1;
    }
    return 0;
}
//上傳文件
int UpLoadFile(tcp_sock& sockCtrl, const char* szPath, const char* szFile)
{
    tcp_sock sockData;
    char    szRespBuf[RESPONSE_BUF_SIZE + 1];
    //切換到根目錄
    if (!SendFtpCmd(sockCtrl, "CWD /"))
    {
        printf("SendFtpCmd CWD error!\n");
        return 1;
    }
    if (GetFtpReponse(sockCtrl, szRespBuf, RESPONSE_BUF_SIZE) != 250)
    {
        printf("GetFtpReponse 250 error!\n");
        return 1;
    }
                                                                                                                                                                           
    //調試,顯示當前目錄
    if (!SendFtpCmd(sockCtrl, "PWD"))
    {
        printf("SendFtpCmd PWD error!\n");
        return 1;
    }
    if (GetFtpReponse(sockCtrl, szRespBuf, RESPONSE_BUF_SIZE) != 257)
    {
        printf("GetFtpReponse 257 error!\n");
        return 1;
    }
                                                                                                                                                                           
    //設置傳送類型爲I
    if (!SendFtpCmd(sockCtrl, "TYPE I"))
    {
        printf("SendFtpCmd \"TYPE I\" error!\n");
        return 1;
    }
    if (GetFtpReponse(sockCtrl, szRespBuf, RESPONSE_BUF_SIZE) != 200)
    {
        printf("GetFtpReponse 200 error!\n");
        return 1;
    }
                                                                                                                                                                               
    //PASV
    if (!SendFtpCmd(sockCtrl, "PASV"))
    {
        printf("SendFtpCmd error!\n");
        return 1;
    }
    if (GetFtpReponse(sockCtrl, szRespBuf, RESPONSE_BUF_SIZE) != 227)
    {
        printf("GetFtpReponse 227 error!\n");
        return 1;
    }
                                                                                                                                                                           
    char* pPos = strchr(szRespBuf, '(');
    if (pPos == NULL)
    {
        printf("GetFtpReponse Pasv error!\n");
        return 1;
    }
    int ip1, ip2, ip3, ip4, port1, port2;
    if (sscanf(pPos, "(%d,%d,%d,%d,%d,%d)", &ip1, &ip2,
        &ip3, &ip4, &port1, &port2) != 6)
    {
        printf("GetFtpReponse Pasv Address error!\n");
        return 1;
    }
                                                                                                                                                                           
    //生成ip與端口
    char szIP[50];
    char szPort[10];
    sprintf(szIP, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);
    sprintf(szPort, "%d", port1*256 + port2);
                                                                                                                                                                           
    //數據鏈接
    if (!sockData.connect(szIP, szPort))
    {
        printf("Data connect error!\n");
        return 1;
    }
                                                                                                                                                                           
    //STOR
    char szCmdSTOR[100];
    sprintf(szCmdSTOR, "STOR %s", szFile);
    if (!SendFtpCmd(sockCtrl, szCmdSTOR))//發送文件的命令
    {
        printf("SendFtpCmd \"STOR %s\" error!\n",szFile);
        return 1;
    }
    if (GetFtpReponse(sockCtrl, szRespBuf, RESPONSE_BUF_SIZE) != 150)
    {
        printf("GetFtpReponse 150 error!\n");
        return 1;
    }
                                                                                                                                                                               
    //把文件讀入緩衝區
    FILE* fp = fopen(szFile, "rb");//必須是rb:二進制打開,只讀
    if(fp == NULL)
    {
        printf("Open file %s Error! \n", szFile);
        return 1;
    }
                                                                                                                                                                               
    char szBuf[DATA_BUF_SIZE];
    int nReaded = 0;
    while(1)
    {
        nReaded = fread(szBuf,sizeof(char), DATA_BUF_SIZE, fp);//讀入到szBuf,最多讀入DATA_BUF_SIZE*sizeof(char)
        //printf("--nReaded:%d\n",nReaded);//測試
        if (nReaded == 0)
            break;
        //szBuf中數據寫入套接字緩衝區併發送
        sockData.write(szBuf, nReaded);
        memcpy(szBuf,"\0",DATA_BUF_SIZE);
        //printf("sended\n\n");//測試
    }
    //printf("out\n");//測試
    sockData.close();
    fclose(fp);
    //接收成功嗎?
    if (GetFtpReponse(sockCtrl, szRespBuf, RESPONSE_BUF_SIZE) != 226)
    {
        printf("GetFtpReponse 226 error!\n");
        return 1;
    }
    return 0;
}
//退出登陸
int LogoutFtp(tcp_sock& sockCtrl)
{
    char    szRespBuf[RESPONSE_BUF_SIZE + 1];
                                                                                                                                                                           
    //QUIT
    if (!SendFtpCmd(sockCtrl, "QUIT"))
    {
        printf("SendFtpCmd Quit error!\n");
        return 1;
    }
    if (GetFtpReponse(sockCtrl, szRespBuf, RESPONSE_BUF_SIZE) != 221)
    {
        printf("GetFtpReponse 221 error!\n");
        return 1;
    }
    return 0;
}
//向ftp服務器發送文件
int FtpPut(const char* szIP, const char* szPath, const char* szFile)
{
    tcp_sock sockCtrl;
    char    szRespBuf[RESPONSE_BUF_SIZE + 1];
                                                                                                                                                                           
    if (ConnectFtp(sockCtrl, szIP) != 0)
        return 1;
    if (LoginFtp(sockCtrl) != 0)
        return 1;
    if (UpLoadFile(sockCtrl, szPath, szFile) != 0)
        return 1;
    LogoutFtp(sockCtrl);
    return 0;
}
相關文章
相關標籤/搜索