我使用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