STM32+LWIP+FTP客戶端下載文件


前提

在學習FTP客戶端之前需要學會socket,FTP客戶端與服務器之間的通訊就是使用socket的過程。

思路:

整個過程需要兩個socket,一個用於與服務器端之間的操作,比如輸入賬號密碼、讀取文件大小或者刪除文件之類的操作,另外一個socket用於接收文件內容、一個流;具體流程看下面的流程圖。

流程圖:

FTP命令:

命令 描述
ABOR 中斷數據連接程序
ACCT 系統特權帳號
ALLO 為服務器上的文件存儲器分配字節
APPE 添加文件到服務器同名文件
CDUP 改變服務器上的父目錄
CWD 改變服務器上的工作目錄
DELE 刪除服務器上的指定文件
HELP 返回指定命令信息
LIST 如果是文件名列出文件信息,如果是目錄則列出文件列表
MODE 傳輸模式(S=流模式,B=塊模式,C=壓縮模式)
MKD 在服務器上建立指定目錄
NLST 列出指定目錄內容
NOOP 無動作,除了來自服務器上的承認
PASS 系統登錄密碼
PASV 請求服務器等待數據連接
PORT
IP 地址和兩字節的端口 ID
PWD 顯示當前工作目錄
QUIT 從 FTP 服務器上退出登錄
REIN 重新初始化登錄狀態連接
REST 由特定偏移量重啟文件傳遞
RETR 從服務器上找回(復制)文件
RMD 在服務器上刪除指定目錄
RNFR 對舊路徑重命名
RNTO 對新路徑重命名
SITE 由服務器提供的站點特殊參數
SMNT 掛載指定文件結構
STAT 在當前程序或目錄上返回信息
STOR 儲存(復制)文件到服務器上
STOU 儲存文件到服務器名稱上
STRU 數據結構(F=文件,R=記錄,P=頁面)
SYST 返回服務器使用的操作系統
TYPE 數據類型(A=ASCII,E=EBCDIC,I=binary)
USER > 系統登錄的用戶名

FTP響應碼:

響應代碼 解釋說明
110 新文件指示器上的重啟標記
120 服務器准備就緒的時間(分鍾數)
125 打開數據連接,開始傳輸
150 打開連接
200 成功
202 命令沒有執行
211 系統狀態回復
212 目錄狀態回復
213 文件狀態回復
214 幫助信息回復
215 系統類型回復
220 服務就緒
221 退出網絡
225 打開數據連接
226 結束數據連接
227 進入被動模式(IP 地址、ID 端口)
230 登錄因特網
250 文件行為完成
257 路徑名建立
331 要求密碼
332 要求帳號
350 文件行為暫停
421 服務關閉
425 無法打開數據連接
426 結束連接
450 文件不可用
451 遇到本地錯誤
452 磁盤空間不足
500 無效命令
501 錯誤參數
502 命令沒有執行
503 錯誤指令序列
504 無效命令參數
530 未登錄網絡
532 存儲文件需要帳號
550 文件不可用
551 不知道的頁類型
552 超過存儲分配
553 文件名不允許

實際使用例子

int FTP_Updata_Check(tFTP_DATA *pFtpData_cmd, tFTP_DATA *pFtpData_data)
{
	int sock_ftp_cmd, sock_ftp_data;
	struct sockaddr_in ftp_cmd, ftp_data;
	uint32_t version_num = 0;
	
	memset(pFtpData_data, 0, sizeof(tFTP_DATA));
	memset(pFtpData_cmd, 0, sizeof(tFTP_DATA));
        if ((sock_ftp_cmd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
	{
		printf("FTP: Socket_cmd application failed. . .");
		return -1;
	}
	ftp_cmd.sin_family = AF_INET;
	ftp_cmd.sin_port = htons(FTP_PORT_IND);
	ftp_cmd.sin_addr.s_addr = inet_addr(FTP_IP_ADDR);
	USER_INFO(ePRINTF_LV2, "FTP: Connect Server IP:%s:%d", FTP_IP_ADDR, FTP_PORT_IND);
	if (connect(sock_ftp_cmd, (struct sockaddr *)&ftp_cmd, sizeof (ftp_cmd)) < 0)
	{
		printf("FTP: The server connection failed. . .");
		closesocket(sock_ftp_cmd);
		return -1;
	}
	read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);
	sprintf(pFtpData_cmd->send_buf, "USER %s\r\n", FTP_USERNAME);
	write(sock_ftp_cmd, pFtpData_cmd->send_buf, strlen(pFtpData_cmd->send_buf));
	read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);
	sprintf( pFtpData_cmd->send_buf, "PASS %s\r\n", FTP_PASS);
	write(sock_ftp_cmd, pFtpData_cmd->send_buf, strlen(pFtpData_cmd->send_buf));
	read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);
	sprintf( pFtpData_cmd->send_buf, "PASV\r\n");
	write(sock_ftp_cmd, pFtpData_cmd->send_buf, strlen(pFtpData_cmd->send_buf));
	read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);
	pFtpData_data->port = ftp_get_port(pFtpData_cmd->recevice_buf);
	if ((sock_ftp_data = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
	{
		printf("FTP: Socket_dat application failed. . .");
		closesocket(sock_ftp_cmd);
		return -1;
	}
	ftp_data.sin_family = AF_INET;
	ftp_data.sin_port = htons(pFtpData_data->port);
	ftp_data.sin_addr.s_addr = inet_addr(FTP_IP_ADDR);
	if (connect(sock_ftp_data, (struct sockaddr *)&ftp_data, sizeof (ftp_data)) < 0)
	{
		printf("FTP: The server connection failed. . .");
		closesocket(sock_ftp_data);
		closesocket(sock_ftp_cmd);
		return -1;
	}
	sprintf(pFtpData_cmd->send_buf, "SIZE abc.text\r\n");
	write(sock_ftp_cmd, pFtpData_cmd->send_buf, strlen(pFtpData_cmd->send_buf));
	memset(pFtpData_cmd->recevice_buf, 0, sizeof(pFtpData_cmd->recevice_buf));
	read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);
	USER_INFO(ePRINTF_LV3, "FTP: <<<<%s", pFtpData_cmd->recevice_buf);
	if(strstr(pFtpData_cmd->recevice_buf, "File not found"))
	{
		printf("FTP: There is no file. return");
		closesocket(sock_ftp_data);
		closesocket(sock_ftp_cmd);
		return 0;
	}
	sprintf(pFtpData_cmd->send_buf, "RETR abc.text\r\n");
	write(sock_ftp_cmd, pFtpData_cmd->send_buf, strlen(pFtpData_cmd->send_buf));
	memset(pFtpData_cmd->recevice_buf, 0, sizeof(pFtpData_cmd->recevice_buf));
	read(sock_ftp_cmd, pFtpData_cmd->recevice_buf, sizeof(pFtpData_cmd->recevice_buf) - 1);
	if(strstr(pFtpData_cmd->recevice_buf, "File not found"))
	{
		printf("FTP: There is no file. return");
		closesocket(sock_ftp_data);
		closesocket(sock_ftp_cmd);

		return 0;
	}
	read(sock_ftp_data, pFtpData_data->recevice_buf, sizeof(pFtpData_data->recevice_buf) - 1);//讀文件內容
	closesocket(sock_ftp_data);
	closesocket(sock_ftp_cmd);

	return 1;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM