国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

FTP客戶端c代碼功能實現(xiàn)

這篇具有很好參考價值的文章主要介紹了FTP客戶端c代碼功能實現(xiàn)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

現(xiàn)在市面上有很多免費的FTP軟件:如FileZilla ,那如果想自己在代碼中實現(xiàn)與ftp服務(wù)器的上傳下載文件該如何實現(xiàn)那??

本質(zhì)上ftp協(xié)議就是TCP基礎(chǔ)上建立的一種協(xié)議,具體如下。

FTP 概述

文件傳輸協(xié)議(FTP)作為網(wǎng)絡(luò)共享文件的傳輸協(xié)議,在網(wǎng)絡(luò)應(yīng)用軟件中具有廣泛的應(yīng)用。FTP的目標(biāo)是提高文件的共享性和可靠高效地傳送數(shù)據(jù)。

在傳輸文件時,F(xiàn)TP 客戶端程序先與服務(wù)器建立連接,然后向服務(wù)器發(fā)送命令。服務(wù)器收到命令后給予響應(yīng),并執(zhí)行命令。FTP 協(xié)議與操作系統(tǒng)無關(guān),任何操作系統(tǒng)上的程序只要符合 FTP 協(xié)議,就可以相互傳輸數(shù)據(jù)。本文主要基于 LINUX 平臺,對 FTP 客戶端的實現(xiàn)原理進(jìn)行詳盡的解釋并闡述如何使用 C 語言編寫一個簡單的 FTP 客戶端。

FTP 協(xié)議

相比其他協(xié)議,如 HTTP 協(xié)議,F(xiàn)TP 協(xié)議要復(fù)雜一些。與一般的 C/S 應(yīng)用不同點在于一般的C/S 應(yīng)用程序一般只會建立一個?Socket?連接,這個連接同時處理服務(wù)器端和客戶端的連接命令和數(shù)據(jù)傳輸。而FTP協(xié)議中將命令與數(shù)據(jù)分開傳送的方法提高了效率。

FTP 使用 2 個端口,一個數(shù)據(jù)端口和一個命令端口(也叫做控制端口)。這兩個端口一般是21 (命令端口)和 20 (數(shù)據(jù)端口)??刂?Socket 用來傳送命令,數(shù)據(jù) Socket 是用于傳送數(shù)據(jù)。每一個 FTP 命令發(fā)送之后,F(xiàn)TP 服務(wù)器都會返回一個字符串,其中包括一個響應(yīng)代碼和一些說明信息。其中的返回碼主要是用于判斷命令是否被成功執(zhí)行了。

命令端口

一般來說,客戶端有一個 Socket 用來連接 FTP 服務(wù)器的相關(guān)端口,它負(fù)責(zé) FTP 命令的發(fā)送和接收返回的響應(yīng)信息。一些操作如“登錄”、“改變目錄”、“刪除文件”,依靠這個連接發(fā)送命令就可完成。

數(shù)據(jù)端口

對于有數(shù)據(jù)傳輸?shù)牟僮鳎饕秋@示目錄列表,上傳、下載文件,我們需要依靠另一個 Socket來完成。

如果使用被動模式,通常服務(wù)器端會返回一個端口號??蛻舳诵枰昧黹_一個 Socket 來連接這個端口,然后我們可根據(jù)操作來發(fā)送命令,數(shù)據(jù)會通過新開的一個端口傳輸。

如果使用主動模式,通??蛻舳藭l(fā)送一個端口號給服務(wù)器端,并在這個端口監(jiān)聽。服務(wù)器需要連接到客戶端開啟的這個數(shù)據(jù)端口,并進(jìn)行數(shù)據(jù)的傳輸。

下面對 FTP 的主動模式和被動模式做一個簡單的介紹。

主動模式 (PORT)

主動模式下,客戶端隨機(jī)打開一個大于 1024 的端口向服務(wù)器的命令端口 P,即 21 端口,發(fā)起連接,同時開放N +1 端口監(jiān)聽,并向服務(wù)器發(fā)出 “port N+1” 命令,由服務(wù)器從它自己的數(shù)據(jù)端口 (20) 主動連接到客戶端指定的數(shù)據(jù)端口 (N+1)。

FTP 的客戶端只是告訴服務(wù)器自己的端口號,讓服務(wù)器來連接客戶端指定的端口。對于客戶端的防火墻來說,這是從外部到內(nèi)部的連接,可能會被阻塞。

被動模式 (PASV)

為了解決服務(wù)器發(fā)起到客戶的連接問題,有了另一種 FTP 連接方式,即被動方式。命令連接和數(shù)據(jù)連接都由客戶端發(fā)起,這樣就解決了從服務(wù)器到客戶端的數(shù)據(jù)端口的連接被防火墻過濾的問題。

被動模式下,當(dāng)開啟一個 FTP 連接時,客戶端打開兩個任意的本地端口 (N > 1024 和 N+1) 。

第一個端口連接服務(wù)器的 21 端口,提交 PASV 命令。然后,服務(wù)器會開啟一個任意的端口 (P > 1024 ),返回如“227 entering passive mode (127,0,0,1,4,18)”。 它返回了 227 開頭的信息,在括號中有以逗號隔開的六個數(shù)字,前四個指服務(wù)器的地址,最后兩個,將倒數(shù)第二個乘 256 再加上最后一個數(shù)字,這就是 FTP 服務(wù)器開放的用來進(jìn)行數(shù)據(jù)傳輸?shù)亩丝?。如得?227 entering passive mode (h1,h2,h3,h4,p1,p2),那么端口號是 p1*256+p2,ip 地址為h1.h2.h3.h4。這意味著在服務(wù)器上有一個端口被開放??蛻舳耸盏矫钊〉枚丝谔栔? 會通過 N+1 號端口連接服務(wù)器的端口 P,然后在兩個端口之間進(jìn)行數(shù)據(jù)傳輸。

主要用到的 FTP 命令

FTP 每個命令都有 3 到 4 個字母組成,命令后面跟參數(shù),用空格分開。每個命令都以 "\r\n"結(jié)束。

要下載或上傳一個文件,首先要登入 FTP 服務(wù)器,然后發(fā)送命令,最后退出。這個過程中,主要用到的命令有 USER、PASS、SIZE、REST、CWD、RETR、PASV、PORT、QUIT。

USER: 指定用戶名。通常是控制連接后第一個發(fā)出的命令?!癠SER gaoleyi\r\n”: 用戶名為gaoleyi 登錄。

PASS: 指定用戶密碼。該命令緊跟 USER 命令后?!癙ASS gaoleyi\r\n”:密碼為 gaoleyi。

SIZE: 從服務(wù)器上返回指定文件的大小。“SIZE file.txt\r\n”:如果 file.txt 文件存在,則返回該文件的大小。

CWD: 改變工作目錄。如:“CWD dirname\r\n”。

PASV: 讓服務(wù)器在數(shù)據(jù)端口監(jiān)聽,進(jìn)入被動模式。如:“PASV\r\n”。

PORT: 告訴 FTP 服務(wù)器客戶端監(jiān)聽的端口號,讓 FTP 服務(wù)器采用主動模式連接客戶端。如:“PORT h1,h2,h3,h4,p1,p2”。

RETR: 下載文件?!癛ETR file.txt \r\n”:下載文件 file.txt。

STOR: 上傳文件?!癝TOR file.txt\r\n”:上傳文件 file.txt。

REST: 該命令并不傳送文件,而是略過指定點后的數(shù)據(jù)。此命令后應(yīng)該跟其它要求文件傳輸?shù)?FTP 命令。“REST 100\r\n”:重新指定文件傳送的偏移量為 100 字節(jié)。

QUIT: 關(guān)閉與服務(wù)器的連接。

FTP 響應(yīng)碼

客戶端發(fā)送 FTP 命令后,服務(wù)器返回響應(yīng)碼。

響應(yīng)碼用三位數(shù)字編碼表示:

第一個數(shù)字給出了命令狀態(tài)的一般性指示,比如響應(yīng)成功、失敗或不完整。

第二個數(shù)字是響應(yīng)類型的分類,如 2 代表跟連接有關(guān)的響應(yīng),3 代表用戶認(rèn)證。

第三個數(shù)字提供了更加詳細(xì)的信息。

第一個數(shù)字的含義如下:

1 表示服務(wù)器正確接收信息,還未處理。

2 表示服務(wù)器已經(jīng)正確處理信息。

3 表示服務(wù)器正確接收信息,正在處理。

4 表示信息暫時錯誤。

5 表示信息永久錯誤。

第二個數(shù)字的含義如下:

0 表示語法。

1 表示系統(tǒng)狀態(tài)和信息。

2 表示連接狀態(tài)。

3 表示與用戶認(rèn)證有關(guān)的信息。

4 表示未定義。

5 表示與文件系統(tǒng)有關(guān)的信息。

Socket 編程的幾個重要步驟

Socket 客戶端編程主要步驟如下:

  1. socket() 創(chuàng)建一個 Socket
  2. connect() 與服務(wù)器連接
  3. write() 和 read() 進(jìn)行會話
  4. close() 關(guān)閉 Socket

Socket 服務(wù)器端編程主要步驟如下:

  1. socket() 創(chuàng)建一個 Socket
  2. bind()
  3. listen() 監(jiān)聽
  4. accept() 接收連接的請求
  5. write() 和 read() 進(jìn)行會話
  6. close() 關(guān)閉 Socket

實現(xiàn) FTP 客戶端上傳下載功能

下面讓我們通過一個例子來對 FTP 客戶端有一個深入的了解。本文實現(xiàn)的 FTP 客戶端有下列功能:

  1. 客戶端和 FTP 服務(wù)器建立 Socket 連接。
  2. 向服務(wù)器發(fā)送 USER、PASS 命令登錄 FTP 服務(wù)器。
  3. 使用 PASV 命令得到服務(wù)器監(jiān)聽的端口號,建立數(shù)據(jù)連接。
  4. 使用 RETR/STOR 命令下載/上傳文件。
  5. 在下載完畢后斷開數(shù)據(jù)連接并發(fā)送 QUIT 命令退出。

經(jīng)過測試可以正常上傳下載數(shù)據(jù),,測試代碼如下:

ftp密碼登陸 c語言,服務(wù)器,網(wǎng)絡(luò),linux

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ftp.h"



#define FTP_SERVER_IP "XXXXXXXX"
#define FTP_SERVER_USER "XXXXX"
#define FTP_SERVER_PASS "XXXXXX"
#define MAX_BUF_LEN 512

typedef struct{
    char usr[32];
    char passwd[32];
    char ser_filepath[512];
    char ser_filename[64];
    char new_filename[64];
    int control_sock;

}ftp_client_st; 

ftp_client_st ftp_st;


int main (int argc , char * argv[])
{
    char str[MAX_BUF_LEN] ={0};
    int ret =-1;
    //
    
    while(1){
        printf("*************\n");
        //printf("Please input the ftp server ip: ");
        memset(str,0,sizeof(str));
        //scanf("%s",str); //從終端獲取到服務(wù)器ip地址。
        strcpy(str,FTP_SERVER_IP);
        printf("input fpt server ip:%s\n",str);
        /*連接到服務(wù)器*/
        memset(&ftp_st,0,sizeof(ftp_client_st));
         ftp_st.control_sock = connect_ftp_server(str,FTP_SERVER_PORT);
        if(ftp_st.control_sock > 0){/*連接成功*/
            ret = -1;
            while(ret < 0){
    
                strcpy(ftp_st.usr,FTP_SERVER_USER);
                strcpy(ftp_st.passwd,FTP_SERVER_PASS);
                printf("input usr:%s passwd:%s\n",ftp_st.usr,ftp_st.passwd);
                ret = login_ftp_server(ftp_st.control_sock,ftp_st.usr,ftp_st.passwd); 
                if(ret < 0){    
                    printf("\nUser or Passwd is wrong,input agin");
                }
                else{
                    //打印服務(wù)器當(dāng)前目錄和列表
                    while(1){
                        
                        printf("Get list start:\n");
                        //ret = down_file_ftpserver(ftp_st.control_sock,"/","/list_mode",0,0,CMD_LIST); /*被動模式*/
                        ret = down_file_ftpserver(ftp_st.control_sock,"/","../list_passive",1,0,CMD_LIST); /*被動模式獲取文件列表*/

                       // down_file_ftpserver(ftp_st.control_sock,"/down_test","list1",0,0,CMD_LIST);

                        //printf("\nInput down file dir (Input quit to quit):");
                        //memset(ftp_st.ser_filepath,0,sizeof(ftp_st.ser_filepath));
                        //scanf("%s",ftp_st.ser_filepath); 
                        
                        //if(strncmp(ftp_st.ser_filepath,"quit",4) ==0)
                        //    goto err0;

                     #if 0  
                        printf("\nInput  down filename (Input quit to quit):");
                        memset(ftp_st.ser_filename,0,sizeof(ftp_st.ser_filename));
                        scanf("%s",ftp_st.ser_filename); 
                        
                        if(strncmp(ftp_st.ser_filename,"quit",4) ==0)
                            goto err0;                        

                        printf("\nInput new filename (Input quit to quit):");
                        memset(ftp_st.new_filename,0,sizeof(ftp_st.new_filename));
                        scanf("%s",ftp_st.new_filename); 
                        
                        if(strncmp(ftp_st.new_filename,"quit",4) ==0)
                            goto err0;    
                        printf("input filename :%s; newfilename:%s; \n",ftp_st.ser_filename,ftp_st.new_filename);
                        
                        printf("down file start:\n");
                        //ret = down_file_ftpserver(ftp_st.control_sock,ftp_st.ser_filename,ftp_st.new_filename,0,0,CMD_RETR);
                        ret = down_file_ftpserver(ftp_st.control_sock,ftp_st.ser_filename,ftp_st.new_filename,0,0,CMD_RETR);
                        #endif
                        down_file_ftpserver(ftp_st.control_sock,"/down_test/test_ftp.zip","../12.zip",1,0,CMD_RETR);
                        up_file_ftpserver(ftp_st.control_sock, "/down_test/12.zip", "../12.zip", 1, 0);
                        get_fsize_ftpserver(ftp_st.control_sock, "/down_test/12.zip");
                        goto err0;

                    }
                    
                }
            }

        }
        
    }

err0:    
    quit_fpt_server(ftp_st.control_sock);
    return 0;

    
}

ftp密碼登陸 c語言,服務(wù)器,網(wǎng)絡(luò),linux

fpt.c

ftp密碼登陸 c語言,服務(wù)器,網(wǎng)絡(luò),linux

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <arpa/inet.h>
#include <sys/unistd.h>

#include <sys/ioctl.h>
#include <net/if.h>


#include "ftp.h"


#define MAX_BUF 512
#define IP_LENGTH   16


//正常時服務(wù)器回復(fù)的響應(yīng)碼
#define ACK_USER_NUM "331"
#define ACK_PASS_NUM "230"
#define ACK_PASV_NUM "227"
#define ACK_CWD_NUM  "250"
#define ACK_SIZE_NUM "213"
#define ACK_RETR_NUM "150" 
#define ACK_REST_NUM "350"
#define ACK_QUIT_NUM "200"
#define ACK_LIST_NUM "125"
#define ACK_STOR_NUM "150"
#define ACK_CONNECT_NUM "220"
#define ACK_PORT_NUM "200"




/*ftp server info*/
typedef struct 
{
    //char szUserName[16];
    //char szPassWd[32];
    char server_path[128];
    char server_filename[64];
    char new_filename[128];
    int data_sock;
    char data_ip[32];
    int  data_port;
    int client_server_sock;
    int file_handle;
}FTP_DATA_INFO;



static int itoa(int value, char * str, int radix);
static int send_cmd(int ctrl_sock,eu_cmd_type typ, const char *val,const char *ack_num);
static int enter_passive_mode(int ctrl_sock,char *data_ip, int * data_port);
static int enter_active_mode(int ctrl_sock);


static int get_data_sock(const char* server_ip,const int port);
static int get_active_data_sock(int client_server_sock);

static int GetAddr(const char *ifname, char *addr, int flag);
static int close_st_info(FTP_DATA_INFO * info);



FTP_DATA_INFO server_info;



static int GetAddr(const char *ifname, char *addr, int flag)
{
    struct sockaddr_in *sin;
    struct ifreq ifr;
    int sockfd;

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        printf("socket create error!\n");
        return - 1;
    }

    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ);

    if(ioctl(sockfd, flag, &ifr) < 0)
    {
        close(sockfd);
        return - 1;
    }

    close(sockfd);

    if(SIOCGIFHWADDR == flag)
    {
        memcpy((void *)addr, (const void *)&ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);
    }
    else
    {
        sin = (struct sockaddr_in *)&ifr.ifr_ifru.ifru_addr;
        snprintf((char *)addr, IP_LENGTH, "%s", inet_ntoa(sin->sin_addr));
    }

    return 0;
}




static int itoa(int value, char * str, int radix)
{
 char temp[33];
  char *tp = temp; 
  int i; 
  unsigned v; 
  int sign; 
  char *sp;
  int num= 0;
  if(radix > 36 || radix < 1) 
    return 0; 
  sign = (radix == 10 && value < 0); //十進(jìn)制負(fù)數(shù) 
  if(sign) 
    v = -value; 
  else
    v = (unsigned)value; 
  while(v || tp == temp)       //轉(zhuǎn)化操作 
  { 
    i = v % radix; 
    v = v / radix; 
    if(i < 10) 
      *tp++ = i + '0'; 
    else
      *tp++ = i + 'a' - 10; 
  } 
  if(str == 0) 
    str = (char*)malloc((tp - temp) + sign + 1); 
  sp = str; 
  if(sign)   //是負(fù)數(shù)的話把負(fù)號先加入數(shù)組 
    *sp++ = '-'; 
  while(tp > temp)
  {
    *sp++ = *--tp;
    num++;
  }
  *sp = 0; 
  
  return num;
}



/*
* @brief 連接fpt服務(wù)器
* @param 無
* @return -1/成功建立的套接字
*/
int connect_ftp_server(const char* server_ip,const int port)
{
    int control_sock =-1;
    int ret =-1;
    struct sockaddr_in server;
    char read_buf[MAX_BUF]={0};
    struct timeval tv_out;
    
    memset(&server,0,sizeof(struct sockaddr_in));
    
    if(server_ip == NULL){
        printf("argc is NULL\n");
        return -1;
    }

    control_sock = socket(AF_INET,SOCK_STREAM,0);
    if(control_sock <0){
        printf("socket failed\n");
        return -1;
    }

    /*設(shè)置sock fd 接收超時時間*/
    tv_out.tv_sec =0;
    tv_out.tv_usec =500*1000;
    setsockopt(control_sock, SOL_SOCKET, SO_RCVTIMEO,&tv_out,sizeof(tv_out));
    
    
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = inet_addr(server_ip); 

    ret = connect(control_sock,(struct sockaddr *)&server,sizeof(server));
    if(ret < 0){
        printf("connect failed\n");
        return -1;
    }

    ret =1;
    
    /*接收服務(wù)端的應(yīng)答消息*/
    usleep(100*1000);
    ret = read(control_sock,read_buf,sizeof(read_buf));
    if(ret < 0){
        printf("read error\n");
        return -1;
    }
    printf("%s ret=%d \n",read_buf,ret);

    if(strncmp(read_buf,ACK_CONNECT_NUM,3) == 0) /*成功*/
    {
        printf("Connect ftp ok\n");
        return control_sock;
    }
    else
    {
        close(control_sock);
        return -1;
    }


}



/*
* @brief 被動模式連接獲取服務(wù)器的data_sock
* @param 無
* @return -1/成功建立的套接字
*/
static int get_data_sock(const char* server_ip,const int port)
{
    int data_sock =-1;
    int ret =-1;
    struct sockaddr_in server;
    char read_buf[MAX_BUF]={0};
    
    memset(&server,0,sizeof(struct sockaddr_in));
    
    if(server_ip == NULL){
        printf("argc is NULL\n");
        return -1;
    }

    data_sock = socket(AF_INET,SOCK_STREAM,0);
    if(data_sock <0){
        printf("socket failed\n");
        return -1;
    }
    /*設(shè)置為非阻塞*/
    //int cflags = fcntl(data_sock,F_GETFL,0);
    //fcntl(data_sock,F_SETFL,cflags|O_NONBLOCK);
    
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = inet_addr(server_ip); 

    ret = connect(data_sock,(struct sockaddr *)&server,sizeof(server));
    if(ret < 0){
        printf("connect failed\n");
        return -1;
    }
    /*無應(yīng)答*/

    return data_sock;

}


/*主動模式獲取data sock 
  必須要在LIST等下載上傳命令發(fā)送后
  accept接受才能成功
  
*/
static int get_active_data_sock(int client_server_sock)
{
    int data_sock =-1;
    struct sockaddr_in client_name;
    int len;

    len = sizeof(client_name);
    data_sock = accept(client_server_sock,(struct sockaddr *)&client_name ,&len);
    if(data_sock <0)
    {
        printf("accept failed\n");
    }
    printf("data_sock = %d\n",data_sock);
    
    return data_sock;
}


/*
* @brief 登陸fpt服務(wù)器
* @param 無
* @return -1/成功返回0
*/
int login_ftp_server(int ctrl_sock,const char *user_name, const char * passwd)
{
    int ret =-1;

    if((user_name == NULL) ||(passwd == NULL)){
        printf("argc is NULL\n");
        return -1;
    }
    
    ret = send_cmd(ctrl_sock,CMD_USER,user_name,ACK_USER_NUM);
    if(ret < 0){
            printf("send_cmd  %d failed \n",CMD_USER);
            return -1;
    }


    ret = send_cmd(ctrl_sock,CMD_PASS,passwd,ACK_PASS_NUM);
    if(ret < 0){
            printf("send_cmd  %d failed \n",CMD_PASS);
            return -1;
    }
    return 0;
}



/*
* @brief 給服務(wù)器發(fā)送指令
* @param 
* @return 失敗返回-1/成功返回0
    SIZE 返回等到的文件大小 
*/

static int send_cmd(int ctrl_sock,eu_cmd_type typ, const char *val,const char *ack_num)
{
    int ret =-1;
    char send_buf[MAX_BUF]={0};
    char read_buf[MAX_BUF]={0};
    char *pos= NULL;
    char tmp[64] ={0};

    if((typ == CMD_USER) ||(typ == CMD_PASS) || (typ == CMD_CWD)){
        if((val == NULL) ||(ack_num == NULL)){
            printf("argc is NULL\n");
            return -1;
        }
    }

    
    switch(typ){
    case CMD_USER:
        memset(send_buf,0,sizeof(send_buf));
        sprintf(send_buf,"USER %s\r\n",val);
        ret = write(ctrl_sock,send_buf,strlen(send_buf));
        if(ret < 0){
            printf("write failed\n");
            return -1;
        }
        memset(read_buf,0,sizeof(read_buf));
        ret = read(ctrl_sock,read_buf,sizeof(read_buf));
        if(ret < 0){
            printf("read failed\n");
            return -1;
        }
        ret = strncmp(read_buf,ack_num,strlen(ack_num));
        break;
    case CMD_PASS:
        memset(send_buf,0,sizeof(send_buf));
        sprintf(send_buf,"PASS %s\r\n",val);
        ret = write(ctrl_sock,send_buf,strlen(send_buf));
        if(ret < 0){
            printf("write failed\n");
            return -1;
        }
        memset(read_buf,0,sizeof(read_buf));
        ret = read(ctrl_sock,read_buf,sizeof(read_buf));
        if(ret < 0){
            printf("read failed\n");
            return -1;
        }
        ret = strncmp(read_buf,ack_num,strlen(ack_num));
        break;
    case CMD_PASV: /*只發(fā)送命令,函數(shù)外面接收提取信息*/
        memset(send_buf,0,sizeof(send_buf));
        sprintf(send_buf,"PASV\r\n");
        ret = write(ctrl_sock,send_buf,strlen(send_buf));
        if(ret < 0){
            printf("write failed\n");
            return -1;
        }
        break;
    case CMD_CWD:
        memset(send_buf,0,sizeof(send_buf));
        sprintf(send_buf,"CWD %s\r\n",val);
        ret = write(ctrl_sock,send_buf,strlen(send_buf));
        if(ret < 0){
            printf("write failed\n");
            return -1;
        }
        usleep(500*1000);
        memset(read_buf,0,sizeof(read_buf));
        ret = read(ctrl_sock,read_buf,sizeof(read_buf));
        if(ret < 0){
            printf("read failed\n");
            return -1;
        }
        ret = strncmp(read_buf,ack_num,strlen(ack_num));
        break;
    case CMD_QUIT:
        memset(send_buf,0,sizeof(send_buf));
        sprintf(send_buf,"QUIT\r\n");
        ret = write(ctrl_sock,send_buf,strlen(send_buf));
        if(ret < 0){
            printf("write failed\n");
            return -1;
        }
        usleep(500*1000);
        memset(read_buf,0,sizeof(read_buf));
        ret = read(ctrl_sock,read_buf,sizeof(read_buf));
        if(ret < 0){
            printf("read failed\n");
            return -1;
        }
    //    ret = strncmp(read_buf,ack_num,strlen(ack_num));

    case CMD_LIST:
        memset(send_buf,0,sizeof(send_buf));
        sprintf(send_buf,"LIST %s\r\n",val);
        ret = write(ctrl_sock,send_buf,strlen(send_buf));
        if(ret < 0){
            printf("write failed\n");
            return -1;
        }
        memset(read_buf,0,sizeof(read_buf));
        usleep(100*1000); /*等待一會把266 也接收回來*/
        ret = read(ctrl_sock,read_buf,sizeof(send_buf));
        if(ret < 0){
            printf("read failed\n");
            return -1;
        }
    //    ret = strncmp(read_buf,ack_num,strlen(ack_num));

        break;

    case CMD_STOR:
        memset(send_buf,0,sizeof(send_buf));
        sprintf(send_buf,"STOR %s\r\n",val);
        ret = write(ctrl_sock,send_buf,strlen(send_buf));
        if(ret < 0){
            printf("write failed\n");
            return -1;
        }
        usleep(50*1000);
        memset(read_buf,0,sizeof(read_buf));
        ret = read(ctrl_sock,read_buf,sizeof(read_buf));
        if(ret < 0){
            printf("read failed\n");
            return -1;
        }
    //    ret = strncmp(read_buf,ack_num,strlen(ack_num));

        break;

    case CMD_RETR:
        memset(send_buf,0,sizeof(send_buf));
        sprintf(send_buf,"RETR %s\r\n",val);
        ret = write(ctrl_sock,send_buf,strlen(send_buf));
        if(ret < 0){
            printf("write failed\n");
            return -1;
        }
        usleep(50*1000);
        memset(read_buf,0,sizeof(read_buf));
        ret = read(ctrl_sock,read_buf,sizeof(read_buf));
        if(ret < 0){
            printf("read failed\n");
            return -1;
        }
    //    ret = strncmp(read_buf,ack_num,strlen(ack_num));

        break;

    case CMD_SIZE_FTP:
        memset(send_buf,0,sizeof(send_buf));
        sprintf(send_buf,"SIZE %s\r\n",val);
        ret = write(ctrl_sock,send_buf,strlen(send_buf));
        if(ret < 0){
            printf("write failed\n");
            return -1;
        }
        usleep(50*1000);
        memset(read_buf,0,sizeof(read_buf));
        ret = read(ctrl_sock,read_buf,sizeof(read_buf));
        if(ret < 0){
            printf("read failed\n");
            return -1;
        }
        /* 客戶端接收服務(wù)器的響應(yīng)碼和信息,正常為 ”213 <size>” */
        pos = strstr(read_buf,ack_num);
        if(pos != NULL){
            pos += strlen(ack_num) +1;
            strcpy(tmp,pos);
            ret = atoi(tmp);
        }
        else{
            ret =-1;
        }
        
        break;    
    case CMD_PORT_FTP:
        memset(send_buf,0,sizeof(send_buf));
        sprintf(send_buf,"PORT %s\r\n",val);
        ret = write(ctrl_sock,send_buf,strlen(send_buf));
        if(ret < 0){
            printf("write failed\n");
            return -1;
        }
        usleep(50*1000);
        memset(read_buf,0,sizeof(read_buf));
        ret = read(ctrl_sock,read_buf,sizeof(read_buf));
        if(ret < 0){
            printf("read failed\n");
            return -1;
        }
        ret = strncmp(read_buf,ack_num,strlen(ack_num));
        break;    
    case CMD_MLSD:
        memset(send_buf,0,sizeof(send_buf));
        sprintf(send_buf,"MLSD\r\n");
        ret = write(ctrl_sock,send_buf,strlen(send_buf));
        if(ret < 0){
            printf("write failed\n");
            return -1;
        }
        break;
    default:break;
    }
    printf("FTP server ack= %s\n",read_buf);    
    return ret;

}





/*
* @brief 進(jìn)入主動模式,讓服務(wù)器主動連接到客戶端的端口
* @param 無
* @return -1/成功返回client_server_sock
*/
static int enter_active_mode(int ctrl_sock)
{
    int data_sock,server_sock;
    struct sockaddr_in name;
    struct sockaddr_in client_name,loc_addr;
    unsigned short server_port =0;
    int ret =-1;
    int len =0;
    char send_buf[64] ={0};
    char ip[20]={0};
    unsigned short  ip0,ip1,ip2,ip3,p1,p2;
    //char read_buf[128] ={0};

    struct timeval tv_out;

    /*設(shè)置sock fd 接收超時時間*/
    tv_out.tv_sec =3;
    tv_out.tv_usec =0;

  /*
    if(GetAddr("eth0", ip, SIOCGIFADDR) != 0)
    {    
         printf("get local ip failed\n");
        return -1;
    }
    printf("local ip =%s\n",ip);
    */
    memset(&name,0,sizeof(name));
    memset(&client_name,0,sizeof(client_name));

    /*通過ctrl_sock獲取到本機(jī)的ip*/
    len =sizeof(name);
    if(getsockname(ctrl_sock,(struct sockaddr*)&name,&len) == -1)
    {
        printf("get sock name failed\n");
        return -1;
    }
    
    sscanf(inet_ntoa(name.sin_addr),"%hu.%hu.%hu.%hu",&ip0,&ip1,&ip2,&ip3);
    
    
    server_sock = socket(AF_INET,SOCK_STREAM,0);
    if(server_sock <0){
        printf("get sock failed\n");
        return -1;
    }
    /*設(shè)置接收超時*/
    setsockopt(server_sock, SOL_SOCKET, SO_RCVTIMEO,&tv_out,sizeof(tv_out));
    
    name.sin_family = AF_INET;
    name.sin_port = 0;
    len = sizeof(name);
    ret = bind(server_sock,(struct sockaddr *)&name,len);
    if(ret < 0){
        printf("bind error\n");
        goto err0;
    }
    
    /*通過ctrl_sock獲取到系統(tǒng)分配到的端口*/
    len = sizeof(loc_addr);
    memset(&loc_addr,0,len);
    ret = getsockname(server_sock,(struct sockaddr *)&loc_addr,&len);
    if(ret < 0)
    {
        printf("get sock name failed\n");
        goto err0;
    }
    server_port = ntohs(loc_addr.sin_port); 

    p1 = server_port/256;
    p2 = server_port%256;

    ret = listen(server_sock,10);
    if(ret < 0)
    {
        printf("listen error\n");
        goto err0;
    }

    /*給服務(wù)器 命令 “PORT       \r\n*/
    /*將ip中的.更換為,*/
#if 0    
    &ip0 = strtok(ip,".");
    &ip1 = strtok(NULL,".");
    &ip2 = strtok(NULL,".");
    &ip3 = strtok(NULL,".");
#endif

    sprintf(send_buf,"%hu,%hu,%hu,%hu,%hu,%hu",ip0,ip1,ip2,ip3,p1,p2);
    printf("send_buf =%s server_port=%d\n",send_buf,server_port);
    ret = send_cmd(ctrl_sock,CMD_PORT_FTP, send_buf,ACK_PORT_NUM);
    if(ret < 0){
        printf("Send PORT failed\n");
        goto err0;
    }

    return server_sock;
err0:
    close(server_sock);
    return -1;
}



/*
* @brief 進(jìn)入被動模式,讓服務(wù)器在數(shù)據(jù)端口監(jiān)聽數(shù)據(jù)
* @param 無
* @return -1/成功返回0
*/

static int enter_passive_mode(int ctrl_sock,char *data_ip, int * data_port)
{
    int ret =-1;
    char read_buf[MAX_BUF]={0};
    char tmp_buf[64]={0};
    unsigned char ip1,ip2,ip3,ip4,port1,port2;
    //char *tmp;

    if((data_ip == NULL) ||(data_port == NULL)){
        printf("argc is NULL\n");
        return -1;
    }
    ret = send_cmd(ctrl_sock,CMD_PASV,NULL,NULL);
    if(ret < 0){
            printf("send_cmd  %d failed \n",CMD_PASV);
            return -1;
    }

    usleep(100*1000);
    ret = read(ctrl_sock,read_buf,sizeof(read_buf));
    if(ret < 0){
        printf("read failed\n");
        return -1;
    }
    printf("rev =%d: %s\n",ret,read_buf);
    if(strstr(read_buf,ACK_PASV_NUM) != NULL){
        
        sscanf(strchr(read_buf,'(')+1,"%hhu,%hhu,%hhu,%hhu,%hhu,%hhu",&ip1,&ip2,&ip3,&ip4,&port1,&port2);
        //printf("ip1=%d,ip2=%d,ip3=%d,ip4=%d,port1 =%d ,port2 = %d\n",ip1,ip2,ip3,ip4,port1,port2);
        
        //snprintf(data_ip,sizeof(data_ip),"%hhu,%hhu,%hhu,%hhu",ip1,ip2,ip3,ip4);

        //memset(data_ip,0,sizeof(data_ip));
        //snprintf(data_ip,sizeof(data_ip),"%d.%d.%d.%d",ip1,ip2,ip3,ip4);
        //printf("data_ip = %s\n",data_ip);

        memset(data_ip,0,sizeof(data_ip));

        memset(tmp_buf,0,sizeof(tmp_buf));
        itoa(ip1,tmp_buf,10);
        strcat(data_ip,tmp_buf);
        strcat(data_ip,".");
        
        memset(tmp_buf,0,sizeof(tmp_buf));
        itoa(ip2,tmp_buf,10);
        strcat(data_ip,tmp_buf);
        strcat(data_ip,".");

        memset(tmp_buf,0,sizeof(tmp_buf));
        itoa(ip3,tmp_buf,10);
        strcat(data_ip,tmp_buf);
        strcat(data_ip,".");

        memset(tmp_buf,0,sizeof(tmp_buf));
        itoa(ip4,tmp_buf,10);
        strcat(data_ip,tmp_buf);
        //printf("data_ip1 = %s\n",data_ip);
    
        *data_port = port1*256+port2;
        
    }
    return 0;

}


/*
* @brief 從ftp服務(wù)器上下載文件
* @param 
  ctrl_sock 控制服務(wù)器sock
  connect_mode= 0 設(shè)置服務(wù)器被動模式下載,非0服務(wù)器主動模式下載
  server_filepath_name 要下載文件的路徑
  newfilename 下載到本地的路徑和文件名字
  offset 設(shè)置下載文件偏移的位置,不偏移寫0 ,可用于錯誤時續(xù)傳。
* @return -1/成功返回未接收到的字節(jié)數(shù)
*/

int down_file_ftpserver(int ctrl_sock, char *server_filepath_name,
const  char *newfilename,int connect_mode,int offset,eu_cmd_type typ)
{
    
    int ret =-1,file_size=0;
    char rec_buf[2048] ={0};
    char stri[128]={0};
    int read_size =0;
    char * pos =NULL;
    char *tmp = NULL;
    int flags =O_CREAT|O_RDWR|O_TRUNC;;

    
    close_st_info(&server_info);

    if(server_filepath_name == NULL  || newfilename == NULL){
        printf("argc is NULL\n");
        return -1;
    }

    
    /*提取出server_path file name*/
    tmp = server_filepath_name;

    if(tmp != NULL){
        while(tmp != NULL){    
            tmp = strstr(tmp,"/");
        //    printf("tmp =%x :%s\n",tmp,tmp);
            if(tmp != NULL){
                pos = tmp;
                tmp++; /*越過找到的"/"*/
            }
        }
        if(pos !=NULL){
            strncpy(server_info.server_path,server_filepath_name,pos-server_filepath_name+1);
            strcpy(server_info.server_filename,pos+1);
        }
        else{
                strcpy(server_info.server_filename,server_filepath_name);
        }
    }

    printf("server path = %s ;file name =%s\n",server_info.server_path,server_info.server_filename);

    if((typ !=CMD_RETR) && (typ !=CMD_LIST)){
        printf("typ value is not CMD_RETR or CMD_LIST\n");
        return -1;    

    }

    if(connect_mode){ /*主動模式*/
    
        server_info.client_server_sock =enter_active_mode(ctrl_sock);
        if(server_info.client_server_sock< 0)
        {
            printf("get data_scok failed\n");
            return -1;
        }

    }else{ /*被動模式*/
        ret = enter_passive_mode(ctrl_sock,server_info.data_ip, &server_info.data_port);
        if(ret < 0){
                printf("set passive mode failed\n");
                return -1;
        }
        printf("server_info.data_ip =%s, data_port =%d \n",server_info.data_ip,server_info.data_port);
        server_info.data_sock = get_data_sock(server_info.data_ip,server_info.data_port);
        if(server_info.data_sock < 0){
            printf("get data sock failed\n");
            return -1;
        }
    }

    /*更改目錄*/
      if(strlen(server_info.server_path) !=0) 
      {
         ret =  send_cmd(ctrl_sock,CMD_CWD,server_info.server_path,ACK_CWD_NUM);
         if(ret < 0){
                printf("set passive mode failed\n");
                goto err0;
         }
      }
      
     if(typ ==CMD_RETR){/*發(fā)送下載文件命令*/

         /*設(shè)置下載文件偏移的位置*/
         if(offset >0){
        
             flags =O_CREAT|O_RDWR|O_APPEND;     
              itoa(offset,stri,10);
             ret =    send_cmd(ctrl_sock,CMD_REST,stri,ACK_REST_NUM);
              if(ret < 0){
                     printf("set file offsize failed\n");
                     goto err0;
              }  
         }
         ret =  send_cmd(ctrl_sock,CMD_RETR,server_info.server_filename,ACK_RETR_NUM);
         if(ret < 0){
                printf("send RETR failed\n");
                goto err0;
         } 
     }
    else if(typ ==CMD_LIST){
         ret =  send_cmd(ctrl_sock,CMD_LIST,server_filepath_name,ACK_LIST_NUM);
         if(ret < 0){
                printf("send LIST failed\n");
                goto err0;
         } 
     }

    if(connect_mode){
        server_info.data_sock= get_active_data_sock(server_info.client_server_sock);
        if(server_info.data_sock <0)
        {
            printf("accept failed\n");
            goto err0;
        }
    }

      server_info.file_handle = open(newfilename,flags,0766);
     if(server_info.file_handle < 0){
        printf("open file failed\n");
            goto err0;
     }
     if(offset >0){
         lseek(server_info.file_handle,offset, SEEK_SET);
         read_size += offset;
     }
     
     for(;;){
         memset(rec_buf,0,sizeof(rec_buf));
        
        ret = recv(server_info.data_sock,rec_buf,sizeof(rec_buf),0);
         if(ret < 0)
         {
            printf("Read error\n");
            goto err1;
        }
        else if(ret == 0)
        {
            ret = read_size;
            goto err1;
        }
        else if(ret >0)
        {
            read_size += ret;
            ret = write(server_info.file_handle,rec_buf,ret);
            if(ret < 0)
            {
                printf("Write error\n");
                goto err1;
            }
            //printf("read_buf =%s\n",rec_buf);
        }
     
     }

    
err1:
    if(server_info.file_handle >0)
        close(server_info.file_handle);
err0:
    if(server_info.client_server_sock > 0)
        close(server_info.client_server_sock);

    if(server_info.data_sock > 0)
        close(server_info.data_sock);
    memset(rec_buf,0,sizeof(rec_buf));
    /* 客戶端接收服務(wù)器的響應(yīng)碼和信息,正常為 ”226 Transfer complete.” */
    read(ctrl_sock,rec_buf,sizeof(rec_buf)); /*有時消息再發(fā)送完命令后里面就能收到,導(dǎo)致會阻塞在這個上面*/
    printf("%s \n Download file end!!\n",rec_buf);
    
    return ret;
    

}



/*
* @brief 上傳文件從ftp服務(wù)器
* @param 
  ctrl_sock 控制服務(wù)器sock
  connect_mode = 0 設(shè)置服務(wù)器被動模式,非0 服務(wù)器主動模式
  server_filepath_name  上傳到服務(wù)器上的文件路徑和名稱
  srcfilename 本地要上傳的路徑和文件名字
  offset 設(shè)置下載文件偏移的位置,不偏移寫0 ,可用于錯誤時續(xù)傳。
* @return -1/成功返回上傳完成的字節(jié)數(shù)
*/

int up_file_ftpserver(int ctrl_sock, char *server_filepath_name,
        const  char *srcfilename,int connect_mode,int offset)

{

    int ret =-1,file_size=0;
    int file_handle =0;
    char rec_buf[2048] ={0};
    int read_size =0;
    char stri[128]={0};
    char *tmp = NULL;
    char * pos =NULL;

    close_st_info(&server_info);
    if((server_filepath_name == NULL) ||(srcfilename == NULL)){
        printf("argc is NULL\n");
        return -1;
    }
    
    /*提取出server_path file name*/
    tmp = server_filepath_name;

    if(tmp != NULL){
        while(tmp != NULL){    
            tmp = strstr(tmp,"/");
        //    printf("tmp =%x :%s\n",tmp,tmp);
            if(tmp != NULL){
                pos = tmp;
                tmp++; /*越過找到的"/"*/
            }
        }
        if(pos !=NULL){
            strncpy(server_info.server_path,server_filepath_name,pos-server_filepath_name+1);
            strcpy(server_info.server_filename,pos+1);
        }
        else{
                strcpy(server_info.server_filename,server_filepath_name);
        }
    }

    printf("server path = %s ;file name =%s\n",server_info.server_path,server_info.server_filename);


    if(connect_mode){ /*主動模式*/
        
        server_info.client_server_sock =enter_active_mode(ctrl_sock);
        if(server_info.client_server_sock <= 0)
        {
            printf("get data_scok failed\n");
            return -1;
        }
        
    }else{ /*被動模式*/
        ret = enter_passive_mode(ctrl_sock,server_info.data_ip, &server_info.data_port);
        if(ret < 0){
                printf("set passive mode failed\n");
                return -1;
        }
        printf("server_info.data_ip =%s, data_port =%d\n",server_info.data_ip,server_info.data_port);
        server_info.data_sock =  get_data_sock(server_info.data_ip,server_info.data_port);
        if(server_info.data_sock < 0){
            printf("get data sock failed\n");
            return -1;
        }
    }
     /*更改目錄*/
       if(strlen(server_info.server_path) !=0) 
       {
          ret =  send_cmd(ctrl_sock,CMD_CWD, server_info.server_path,ACK_CWD_NUM);
          if(ret < 0){
                 printf("set passive mode failed\n");
                 goto err0;
          }
       }

     /*設(shè)置上傳文件偏移的位置*/
     if(offset >0){
          itoa(offset,stri,10);
         ret =    send_cmd(ctrl_sock,CMD_REST,stri,ACK_REST_NUM);
          if(ret < 0){
                 printf("set file offsize failed\n");
                 goto err0;
          }  
     }

    /*發(fā)送上傳文件命令*/
     ret =  send_cmd(ctrl_sock,CMD_STOR,server_info.server_filename,ACK_STOR_NUM);
     if(ret < 0){
            printf("send STOR failed\n");
            goto err0;
     } 
     
     if(connect_mode){
        server_info.data_sock= get_active_data_sock(server_info.client_server_sock);
        if(server_info.data_sock <0)
        {
            printf("accept failed\n");
            goto err0;
        }
    }
          
      server_info.file_handle = open(srcfilename,O_RDONLY);
     if(server_info.file_handle < 0){
        printf("open file failed\n");
            goto err0;
     }
     if(offset >0){
         lseek(server_info.file_handle,offset, SEEK_SET);
         read_size += offset;
     }
     
     for(;;){
         memset(rec_buf,0,sizeof(rec_buf));
        ret = read(server_info.file_handle,rec_buf,sizeof(rec_buf));
         if(ret < 0)
         {
             printf("read file error\n");
            goto err1;
        }
        else if(ret == 0)
        {
            ret = read_size;
            goto err1;
        }
        else if(ret >0)
        {
            //printf("read_buf =%s\n",rec_buf);
            
            ret = write(server_info.data_sock,rec_buf,ret);
            if(ret < 0)
            {
                    printf("Write failed\n");
                    goto err1;
    
            }else{
                  read_size += ret;
                // lseek(file_handle,read_size, SEEK_SET);
            }    
        }
     }

err1:
    if(server_info.file_handle >0)
        close(server_info.file_handle);
err0:
    if(server_info.client_server_sock > 0)
        close(server_info.client_server_sock);

    if(server_info.data_sock > 0)
        close(server_info.data_sock);
    memset(rec_buf,0,sizeof(rec_buf));
    /* 客戶端接收服務(wù)器的響應(yīng)碼和信息,正常為 ”226 Transfer complete.” */
    read(ctrl_sock,rec_buf,sizeof(rec_buf)); 
    printf("%s\n Up file end!!!\n",rec_buf);
    
    return ret;
    

}


static int close_st_info(FTP_DATA_INFO * info)
{
    if(info == NULL)
        return -1;

    if(info->file_handle >0)
        close(info->file_handle);

    if(info->client_server_sock > 0)
        close(info->file_handle);

    if(info->data_sock > 0)
        close(info->file_handle);

    memset(info,0,sizeof(FTP_DATA_INFO));
    return 0;
}


int get_fsize_ftpserver(int ctrl_sock, char *server_filepath_name)
{
    int ret =-1;

    if(server_filepath_name ==NULL){
        printf("argc is null\n");
        return -1;
    }
        /*發(fā)送上傳文件命令*/
     ret =  send_cmd(ctrl_sock,CMD_SIZE_FTP,server_filepath_name,ACK_SIZE_NUM);
     if(ret < 0){
            printf("send SZIE failed\n");
            return -1;
     } 
    //printf("file size =%d\n",ret);
    return ret;
}




/*
* @brief 從ftp服務(wù)器退出
* @param 
  ctrl_sock 控制服務(wù)器sock
* @return -1/成功返回0
*/
int quit_fpt_server(int ctrl_sock)
{
    int ret =-1;
    close_st_info(&server_info);
    
    ret = send_cmd(ctrl_sock,CMD_QUIT,NULL,ACK_QUIT_NUM);
    if(ret < 0)
        printf("quit fpt server error\n");

    close(ctrl_sock);
    
    return ret;
}

ftp密碼登陸 c語言,服務(wù)器,網(wǎng)絡(luò),linux

fpt.h

ftp密碼登陸 c語言,服務(wù)器,網(wǎng)絡(luò),linux

#ifndef __FTP_H__
#define __FTP_H__

#define FTP_SERVER_PORT 21

typedef enum
{
    CMD_USER =0, /*用戶名*/
    CMD_PASS,    /*密碼*/
    CMD_PASV,    /*讓服務(wù)器進(jìn)入被動模式*/
    CMD_CWD,     /*切換工作目錄*/
    CMD_SIZE_FTP,    /*獲取文件大小*/
    CMD_RETR,    /*下載文件*/
    CMD_REST,      /*指定下載文件的偏移量*/
    CMD_QUIT,      /*退出命令*/ 
    CMD_LIST,    /*列表*/
    CMD_STOR,    /*上傳文件*/    
    CMD_PORT_FTP,/*發(fā)送客戶端端口給服務(wù)器*/
    CMD_MLSD, /*列表*/
    
}eu_cmd_type;



int connect_ftp_server(const char* server_ip,const int port);

int login_ftp_server(int ctrl_sock,const char *user_name, const char * passwd);

int down_file_ftpserver(int ctrl_sock, char *server_filepath_name,
    const  char *newfilename,int connect_mode,int offset,eu_cmd_type typ);


int up_file_ftpserver(int ctrl_sock, char *server_filepath_name,
        const  char *srcfilename,int connect_mode,int offset);

int get_fsize_ftpserver(int ctrl_sock, char *server_filepath_name);


int quit_fpt_server(int ctrl_sock);




#endif

ftp密碼登陸 c語言,服務(wù)器,網(wǎng)絡(luò),linux

遇到的主要問題記錄:

  1、實現(xiàn)FTP主動模式的時候,開始的accpet一直無法接收到服務(wù)器的連接請求。

后來用wireshark跟蹤FileZilla與服務(wù)器直接的通信數(shù)據(jù)才找到問題所在。原來accept要在

必須要在LIST等下載上傳命令發(fā)送后服務(wù)器才會連接過來。

? ? ? 2、主要一定要關(guān)閉掉防火墻

? ? ? 3、ftp還有一些傳送方法類型的選擇,本代碼中并沒有進(jìn)行設(shè)置,后續(xù)用到的時候再進(jìn)行完善。

 ?4、 代碼中接收服務(wù)器回復(fù)的時候增加了不少延遲。后來我有在sock?上設(shè)置接收超時,延遲太多反正感覺不是太好。

? ?5、最近更換了一個ftp服務(wù)器平臺時,發(fā)現(xiàn)新問題。發(fā)現(xiàn)下載后的文件大小變大了。經(jīng)過對比發(fā)現(xiàn)多了很多0D .

從網(wǎng)上查詢發(fā)現(xiàn)時Linux系統(tǒng)的回車時\n.?而windows系統(tǒng)的回車時\r\n。?所以當(dāng)ftp?采用ascii方式傳播的時候是有著問題的。

解決方法是發(fā)送TYPE? I\r\n命令將傳輸方式設(shè)置為二進(jìn)制傳輸 。問題解決。

命令及響應(yīng)碼文章來源地址http://www.zghlxwxcb.cn/news/detail-782563.html

命令 描述
ABOR 中斷數(shù)據(jù)連接程序
ACCT <account> 系統(tǒng)特權(quán)帳號
ALLO <bytes> 為服務(wù)器上的文件存儲器分配字節(jié)
APPE <filename> 添加文件到服務(wù)器同名文件
CDUP <dir path> 改變服務(wù)器上的父目錄
CWD <dir path> 改變服務(wù)器上的工作目錄
DELE <filename> 刪除服務(wù)器上的指定文件
HELP <command> 返回指定命令信息
LIST <name> 如果是文件名列出文件信息,如果是目錄則列出文件列表
MODE <mode> 傳輸模式(S=流模式,B=塊模式,C=壓縮模式)
MKD <directory> 在服務(wù)器上建立指定目錄
NLST <directory> 列出指定目錄內(nèi)容
NOOP 無動作,除了來自服務(wù)器上的承認(rèn)
PASS <password> 系統(tǒng)登錄密碼
PASV 請求服務(wù)器等待數(shù)據(jù)連接
PORT <address> IP 地址和兩字節(jié)的端口 ID
PWD 顯示當(dāng)前工作目錄
QUIT 從 FTP 服務(wù)器上退出登錄
REIN 重新初始化登錄狀態(tài)連接
REST <offset> 由特定偏移量重啟文件傳遞
RETR <filename> 從服務(wù)器上找回(復(fù)制)文件
RMD <directory> 在服務(wù)器上刪除指定目錄
RNFR <old path> 對舊路徑重命名
RNTO <new path> 對新路徑重命名
SITE <params> 由服務(wù)器提供的站點特殊參數(shù)
SMNT <pathname> 掛載指定文件結(jié)構(gòu)
STAT <directory> 在當(dāng)前程序或目錄上返回信息
STOR <filename> 儲存(復(fù)制)文件到服務(wù)器上
STOU <filename> 儲存文件到服務(wù)器名稱上
STRU <type> 數(shù)據(jù)結(jié)構(gòu)(F=文件,R=記錄,P=頁面)
SYST 返回服務(wù)器使用的操作系統(tǒng)
TYPE <data type> 數(shù)據(jù)類型(A=ASCII,E=EBCDIC,I=binary)
USER <username> 系統(tǒng)登錄的用戶名
響應(yīng)代碼 解釋說明
110 新文件指示器上的重啟標(biāo)記
120 服務(wù)器準(zhǔn)備就緒的時間(分鐘數(shù))
125 打開數(shù)據(jù)連接,開始傳輸
150 打開連接
200 成功
202 命令沒有執(zhí)行
211 系統(tǒng)狀態(tài)回復(fù)
212 目錄狀態(tài)回復(fù)
213 文件狀態(tài)回復(fù)
214 幫助信息回復(fù)
215 系統(tǒng)類型回復(fù)
220 服務(wù)就緒
221 退出網(wǎng)絡(luò)
225 打開數(shù)據(jù)連接
226 結(jié)束數(shù)據(jù)連接
227 進(jìn)入被動模式(IP 地址、ID 端口)
230 登錄因特網(wǎng)
250 文件行為完成
257 路徑名建立
331 要求密碼
332 要求帳號
350 文件行為暫停
421 服務(wù)關(guān)閉
425 無法打開數(shù)據(jù)連接
426 結(jié)束連接
450 文件不可用
451 遇到本地錯誤
452 磁盤空間不足
500 無效命令
501 錯誤參數(shù)
502 命令沒有執(zhí)行
503 錯誤指令序列
504 無效命令參數(shù)
530 未登錄網(wǎng)絡(luò)
532 存儲文件需要帳號
550 文件不可用
551 不知道的頁類型
552 超過存儲分配
553 文件名不允許

到了這里,關(guān)于FTP客戶端c代碼功能實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包