首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

從零打造 Java FTP 伺服器:核心協定實作與程式碼解析

     編輯:Java 相關知識

前言

FTP (File Transfer Protocol) 是網路上最基礎的檔案傳輸協定之一。雖然現代開發多使用 SFTP 或 HTTP API,但理解 FTP 伺服器的內部運作機制,對於網路程式設計、協定解析與舊系統維護仍具高度教學價值。本文將帶您逐步實作一個支援主動/被動模式、登入驗證、目錄操作、檔案上傳下載的 Java FTP 伺服器。

一、FTP 協定核心概念

  • 雙通道設計:命令通道 (預設 Port 21) 處理指令;資料通道 (Port 20 或動態) 傳輸檔案內容。
  • 傳輸模式:ASCII (文字) 與 Binary (二進位) 模式。
  • 連線模式:
    • 主動模式:Client 告知 IP/Port,Server 主動連回 (PORT 指令)。
    • 被動模式:Server 開啟隨機 Port 並告知 Client 連線 (PASV 指令),穿透防火牆較佳。
  • 常用指令:USER/PASS (登入)、PWD/CWD (目錄)、LIST/NLST (列表)、RETR/STOR (下載/上傳)、QUIT (離開)。

二、伺服器架構設計

2.1 主執行緒:監聽與分派

ServerA 類別建立 ServerSocket 監聽指定 Port,每接受一個 Client 連線,即啟動一條 ClientThread 處理該 Session。

public class ServerA {
    public static void main(String[] args) {
        final int PORT = 21; // 標準 FTP Port
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("FTP Server started on port " + PORT);
            while (true) {
                Socket client = serverSocket.accept();
                new ClientThread(client, "C:/ftp_root").start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.2 ClientThread:指令解析與狀態機

每個執行緒維護自己的狀態:登入狀態、目前工作目錄、資料通道 Socket 等。核心迴圈讀取指令,轉大寫比對,委派對應處理邏輯。

public class ClientThread extends Thread {
    private Socket socket;
    private String rootDir;
    private boolean loggedIn = false;
    private String username;
    private Socket dataSocket; // 主動/被動模式建立的資料連線

    // 建構子、run() 迴圈、指令分派 switch-case 略
    // 關鍵方法:handleUser(), handlePass(), handlePort(), handlePasv()
    //          handleRetr(), handleStor(), handleList(), handleNlst()
}

2.3 處理 PORT (主動模式)

Client 傳送 PORT h1,h2,h3,h4,p1,p2,Server 解析 IP 為 h1.h2.h3.h4,Port 為 p1*256 + p2,主動發起 Socket 連線。

2.4 處理 PASV (被動模式)

Server 建立 ServerSocket 綁定隨機高位 Port,回傳 227 Entering Passive Mode (ip1,ip2,ip3,ip4,p1,p2),等待 Client 連線 accept()。

2.5 檔案傳輸實作 (RETR/STOR)

使用 RandomAccessFile 配合資料通道的 InputStream/OutputStream 進行區塊讀寫 (1024 bytes buffer),支援斷點續傳基礎。

三、日誌與設定

整合 log4j 記錄連線資訊、指令流向、錯誤堆疊,方便除錯與稽核。設定檔 log4j.properties 定義 Console、Daily Rolling File、Error 專屬 Appender。

四、編譯與執行步驟

  1. 確保 JDK 環境與 log4j.jar 在 Classpath。
  2. 編譯所有 .java 檔案。
  3. 執行 java ServerA 啟動伺服器。
  4. 使用 FTP Client (FileZilla、命令列 ftp) 連線測試:
    ftp localhost 21 -> 輸入 root/root -> ls, get test.txt, put local.txt。

五、安全性與擴充建議

  • 生產環境務必改用 SFTP (SSH File Transfer Protocol) 或 FTPS (FTP over TLS),本範例為明文傳輸,不具安全性。
  • 加入 IP 白名單、連線數限制、頻寬控制、虛擬使用者映射系統帳號等企業級功能。
  • 資料通道支援 IPv6、EPSV/EPRT 指令。

六、結語

親手實作 FTP 伺服器,不僅能深入理解 RFC 959 協定細節,更能訓練 Socket 程式設計、多執行緒併發、狀態機設計等核心能力。完整程式碼已上傳 GitHub (連結略),歡迎 Fork 實驗擴充。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved