ftp文件上傳

我使用Ser-U在本地創建了一個ftp
java

若是沒有防火牆,而且實現最簡單的功能,這樣寫就好了。apache

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Test {
    public static void  main(String[] args){
        FTPClient ftpClient = new FTPClient();
        try{
            File file = new File("D:\\downLoad\\笛子基本教程.pdf");
            ftpClient.setDefaultPort(21);//端口號
            ftpClient.connect("127.0.0.1");//服務器地址
            ftpClient.login("rainmanqqst","888888");//用戶名和密碼
            int reply = ftpClient.getReplyCode();//獲取鏈接狀況,230爲登錄成功
            if(!FTPReply.isPositiveCompletion(reply)){//檢查是否登錄成功,值開頭爲2
                ftpClient.disconnect();
                System.err.println("FTP refused connection");
            }else{
                
            }
            ftpClient.storeFile("A.pdf",new FileInputStream(file));//傳輸文件,將文件名設爲A.pdf
            ftpClient.disconnect();
        }catch (IOException a){
            a.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

然而正式使用的時候,防火牆是一個繞不過去的坎,因此ftp的模式就必須加入進來了。安全

ftp使用的是TCP協議,一般使用兩個端口,命令端口(用於接受命令請求)和數據端口(發出數據)。服務器

ftp能夠分主動模式(PORT)和被動模式(PASV)。在主動模式中,客戶端會使用本身的一個N端口訪問服務器的21命令端口,同時開啓一個N+1的端口用於監聽。而服務端在收到客戶端的請求時,會將本身的數據端口20,試圖鏈接到客戶端的N+1端口。在被動模式中客戶端會首先向服務端聲明被動模式,而後開啓兩個端口N和N+1,其中N端口會鏈接服務器的21端口,而後服務器告訴客戶端一個任意的端口P,客戶端會試圖使用N+1端口鏈接上P。post

在使用主動模式時,服務端會主動鏈接客戶端,可是在這個過程當中鏈接可能被客戶端的防火牆阻止。由於客戶端只提供了N+1端口,可能正被防火牆保護着,因此鏈接不上,N爲大於1024的任意值,因此使用特定的規則也有難度。其結果就是客戶端不得不放開本身的防火牆策略,天然而然的會有些安全隱患。.net

在使用被動模式時,因爲客戶端會主動鏈接服務端的P端口,因此在這個時候,P(P:爲默認值)端口可能被防火牆保護着,因此爲了實現ftp鏈接,它必須開放本身的防火牆。在這個時候服務端變得不安全了。不過在使用被動模式時,因爲服務端提供的數據端口P是任意的,不想主動模式中的20是默認的,因此下降了被人竊取數據的風險。從這點看,它又是安全的。code

考慮到這點,代碼就必須作出些調整。blog

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Test {
    public static void  main(String[] args){
        FTPClient ftpClient = new FTPClient();
        try{
            File file = new File("D:\\downLoad\\笛子基本教程.pdf");
            ftpClient.setDefaultPort(21);
            ftpClient.connect("127.0.0.1");
            ftpClient.login("rainmanqqst","888888");
            int reply = ftpClient.getReplyCode();
            if(!FTPReply.isPositiveCompletion(reply)){
                ftpClient.disconnect();
                System.err.println("FTP refused connection");
            }else{
                
            }
            ftpClient.enterLocalPassiveMode();//
            ftpClient.storeFile("A.pdf",new FileInputStream(file));
            ftpClient.disconnect();
        }catch (IOException a){
            a.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

使用主動模式時,若是服務器20號端口沒有開放,在程序運行的過程當中,會一直試圖鏈接,致使運行如下代碼時,停滯不前
教程

            if(!FTPReply.isPositiveCompletion(reply)){
                ftpClient.disconnect();
                System.err.println("FTP refused connection");
            }else{
                
            }

解決方法是去服務端手動開放20端口,或者採用被動模式。get

或者是雖然採用被動模式,可是服務端的防火牆阻止了鏈接。這時候,就不是代碼的問題了,要去服務器的防火牆,修改一下配置。

參考資料:

http://chenyoulu.diandian.com/post/2012-11-20/40042052590

http://jackiechen.blog.51cto.com/196075/193883

http://my.oschina.net/caiyuan/blog/6707

相關文章
相關標籤/搜索