日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt5.10编写FTP客户端

發布時間:2023/12/20 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt5.10编写FTP客户端 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

自從Qt5刪除了QFtp模塊后,就沒有了可方便使用的FTP類。根據官方的說法,是因為該模塊實現質量不好被刪除,而用Qt5的網絡模塊就可以輕松實現。對于初學者沒了現成的工具就不知道該咋辦了。本文從FTP協議開始講起,先明白FTP協議是一個怎樣的結構。然后講解如何用代碼去實現。

全文分兩大部分,第一部分是FTP協議的講解,第二部分是Qt5的代碼實現。筆者會盡量用簡潔明了的語句給列為講清楚的,讓我們開始吧~~

  • FTP協議
  • Qt5的代碼實現

  • 第一部分 FTP協議

    什么是FTP協議?

    就是傳文件用的協議。整個過程就是先用TCP與服務器建立連接,然后發送命令,服務器執行并進行反饋。

    FTP的兩個端口

    一般的客戶端/服務器之間是開一個Socket端口,既傳輸命令又傳輸數據。而FTP的協議中說:我要開兩個端口,一個傳輸命令,一個傳輸數據。

    • 傳輸命令端口(21)
    • 傳輸數據端口(20)

    所以在編程的時候要創建兩個QTcpSocket哦~

    FTP的兩種過程

    分為被動模式和主動模式。這是從客戶端的角度來說的。比如常見的被動模式意思就是服務器告訴你我們用哪個端口進行數據傳輸,我們(客戶端)沒有指定端口的權力,它(服務器)說用啥端口我們(客戶端)就用啥端口。

    而主動模式就是我們(客戶端)自己定好用哪個端口,告訴了服務器,然后雙方在這個端口下進行通信。

    • 被動模式(常用)

    根據上文所述,既然都“被動”了,那我們客戶端就等著服務器給我們分配端口號吧。

    (1)首先我們任意打開一個端口N連接FTP服務器,并在Socket中寫“PASV”命令。這里的N必須大于1024;

    (2)然后服務器會返回個信息,類似“227 Entering Passive Mode(47,94,99,120,39,18)”這樣。前四個是服務器IP地址,后兩個是和分配的端口號相關的數。從這條信息我們就知道了服務器給我們分配的用于數據傳輸的端口號是:39*256+18;

    (3)然后我們就打開第二個端口N+1和服務器的這個39*256+18端口進行連接,然后數據傳輸。

    • 主動模式

    根據上文所述,既然都“主動”了,那我們客戶端就自由分配進行數據傳輸的端口號吧。

    (1)第一步還是任意打開兩個端口N和N+1,先用N端口連接FTP服務器的21端口,同時第二個端口N+1進行監聽。在第一個端口發送“port N+1”命令;

    (2)這時服務器就會主動連接到我們的N+1端口上了。

    FTP命令及響應碼

    FTP命令

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

    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:文件名不允許

    第二部分 FTP的Qt5的代碼實現

    網絡編程三步驟:Socket連接、Write/Read讀寫、Close關閉
    • 被動模式的代碼實現

    一般的服務器都是采用被動模式,所以先講解這部分。

    1/3 Socket連接

    /* 構造Socket,并連接 */ socket = new QTcpSocket(this); connect(socket,&QTcpSocket::connected,this,&MainWindow::slotConnected); connect(socket,&QTcpSocket::readyRead,this,&MainWindow::dataReceived); socket->connectToHost("47.94.99.120",21);

    有兩個槽,slotConnected()槽的作用是如果Socket和服務器建立連接,就在textEdit上顯示“已建立Socket連接”的字樣;dataeceived()槽的作用是顯示服務器反饋回來的信息。

    • void slotConnected()槽
    void MainWindow::slotConnected() {ui->textEdit->append("已建立Socket連接"); }
    • void dataReceived()槽
    void MainWindow::dataReceived() {while (socket->bytesAvailable()){/* 讀取Socket并存入datagram */QByteArray datagram = socket->readAll();/* 展示在textEdit */QString str = QString::fromLocal8Bit(datagram);ui->textEdit->append(str);} }

    看下效果:

    通過連接,服務器反饋回“220 (vsFTPd 3.0.2)”的信息。由上文所述,220響應碼的含義是“服務就緒”。那么接下來就是write/read過程了。

    2/3 Write/Read讀寫

    “發送命令”按鈕的代碼:

    void MainWindow::on_pbSend_clicked() {QByteArray command = ui->lineEdit->text().toLatin1();command += '\n';socket->write(command); } 注意:命令結尾不要忘了加個'\n'回車符號。

    發送 USEuser_name 用戶名

    發送 PASS xxxxxxx 密碼

    發送 PASV 命令

    到此為止,服務器給我們回復“227 Entering Passive Mode(47,94,99,120,39,16)”的響應碼,這是要告訴我們“應該采用被動模式”,后面還附帶了服務器IP地址,以及兩個變量。通過計算得知,服務器給我們分配的數據傳輸端口號是:39*256+16=10000。

    接下來就是再構造一個Socket,端口號為10000,去連接服務器的20端口號(傳輸數據用)。然后各種命令,接受的文件也用Socket的read()等函數去接受,然后QFile各種存文件操作等等等等。


    接下來的步驟就不寫了,FTP協議屬于應用層的部分,具體如何按照這個標準去組織語言就是列位發揮的部分了。

    剛開始我寫FTP協議的時候摸不著頭腦,也不懂HTTP協議、FTP協議等內容,后來經過摸索才知道:哦,這就是應用層的東西。人家都已經告訴你如何去實現FTP的過程了,我們就照著這個過程寫程序就是咯。

    所以整個過程還是很簡單的,就是用Socket去你來我往的交流而已,沒有涉及多么高大上的東西。FTP協議很簡單吧~

    總結

    以上是生活随笔為你收集整理的Qt5.10编写FTP客户端的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。