圖-FileZilla
FileZilla FTP是一個著名的開源標準FTP用戶端軟體,但是它的目前版本與FtpAnywhere提供的網格FTP有相容問題,而且,目前無法通過它提供的那些設定模組來實現相容,因此,我特地下載了它的原始碼快照 [2009.4.16] ,看看是否有可能通過修改原始碼來讓它相容.
解壓縮它的原始碼,轉到子目錄\src\engine下,開啟ftpcontrolsocket.cpp檔案,這個檔案就是FileZilla用來支援標準FTP指令的核心,需要改造的是它的列表模式以及對PASV反饋的分析代碼 [包括IPV6下的EPSV指令,但是暫時因為沒有IPV6,所以沒必要動它],改造它的PASV解析代碼
讓FileZilla相容FtpAnywhere
 
  - bool CFtpControlSocket::ParsePasvResponse(CRawTransferOpData* pData)  
 
  -  
 
  - {  
 
  -  
 
  - // Validate ip address  
 
  -  
 
  - wxString digit = _T("0*[0-9]{1,3}");  
 
  -  
 
  - const wxChar* dot = _T(",");  
 
  -  
 
  - wxString exp = _T("( |\\()(") + digit + dot + digit + dot + digit + dot + digit + dot + digit + dot + digit + _T(")( |\\)|$)");  
 
  -  
 
  - wxRegEx regex;  
 
  -  
 
  - regex.Compile(exp);  
 
  -  
 
  - if (!regex.Matches(m_Response))  
 
  -  
 
  - return false;  
 
  -  
 
  - pData->host = regex.GetMatch(m_Response, 2);  
 
  -  
 
  - int i = pData->host.Find(',', true);  
 
  -  
 
  - long number;  
 
  -  
 
  - if (i == -1 || !pData->host.Mid(i + 1).ToLong(&number))  
 
  -  
 
  - return false;  
 
  -  
 
  - pData->port = number; //get ls byte of server socket  
 
  -  
 
  - pData->host = pData->host.Left(i);  
 
  -  
 
  - i = pData->host.Find(',', true);  
 
  -  
 
  - if (i == -1 || !pData->host.Mid(i + 1).ToLong(&number))  
 
  -  
 
  - return false;  
 
  -  
 
  - pData->port += 256 * number; //add ms byte of server socket  
 
  -  
 
  - pData->host = pData-> host.Left(i);  
 
  -  
 
  - pData->host.Replace(_T(","), _T("."));  
 
  -  
 
  - if (m_pProxyBackend)  
 
  -  
 
  - {  
 
  -  
 
  - // We do not have any information about the proxy's inner workings  
 
  -  
 
  - return true;  
 
  -  
 
  - }  
 
 
//注意,把下面的代碼登出,就可以支援P2P PASV模式下的串連傳輸了
 
  - //const wxString peerIP = m_pSocket->GetPeerIP();  
 
  -  
 
  - //if (!IsRoutableAddress(pData->host, m_pSocket->GetAddressFamily()) && IsRoutableAddress(peerIP, m_pSocket->GetAddressFamily()))  
 
  -  
 
  - //{  
 
  -  
 
  - //if (!m_pEngine->GetOptions()->GetOptionVal(OPTION_PASVREPLYFALLBACKMODE) || pData->bTriedActive)  
 
  -  
 
  - //{  
 
  -  
 
  - //LogMessage(Status, _("Server sent passive reply with unroutable address. Using server address instead."));  
 
  -  
 
  - //LogMessage(Debug_Info, _T(" Reply: %s, peer: %s"), pData->host.c_str(), peerIP.c_str());  
 
  -  
 
  - //pData->host = peerIP;  
 
  -  
 
  - //}  
 
  -  
 
  - //else  
 
  -  
 
  - //{  
 
  -  
 
  - //LogMessage(Status, _("Server sent passive reply with unroutable address. Passive mode failed."));  
 
  -  
 
  - //LogMessage(Debug_Info, _T(" Reply: %s, peer: %s"), pData->host.c_str(), peerIP.c_str());  
 
  -  
 
  - //return false;  
 
  -  
 
  - //}  
 
  -  
 
  - //}  
 
  -  
 
  - return true;  
 
  -  
 
  - }  
 
 
那麼現在的代碼,只要在網站屬性的串連模式裡,指定PORT為優先,在PORT模式串連失敗後,設定自動切換到PASV模式,已經可以有條件相容,只是第一次下載會失敗而已,下面我們改造它的列表模式,讓它具備更好的相容性. 當然,你可以在FtpAnywhere伺服器裡,設定禁止根目錄下PASV列表,來讓FileZilla自動判斷串連模式,但是從它的代碼看,它的判斷還是存在一點相容問題.因此,將LIST改造成主動模式優先,是最好的選擇.
問題在這裡
 
  - CRawTransferOpData::CRawTransferOpData()  
 
  -  
 
  - : COpData(cmd_rawtransfer)  
 
  -  
 
  - {  
 
  -  
 
  - bTriedPasv = bTriedActive = false;  
 
  -  
 
  - bPasv = true;  
 
  -  
 
  - }  
 
 
它的初始化是被動模式優先,這樣,列表的時候將發生問題,但是下載可以成功,但是我閱讀代碼,發現除非額外指定一個列表時優先使用的模式變數,否則很難修改代碼,因為它的代碼中列表和檔案傳輸的優先模式是一致的,還要適應其他標準FTP網站,畢竟我不可以能讓它為我的FtpAnywhere進行最佳化,方法是,在FtpControlSocket.h裡定義的類
 
  - class CRawTransferOpData : public COpData  
 
  -  
 
  - {  
 
  -  
 
  - public:  
 
  -  
 
  - CRawTransferOpData();  
 
  -  
 
  - wxString cmd;  
 
  -  
 
  - CFtpTransferOpData* pOldData;  
 
  -  
 
  - bool bPasv;  
 
  -  
 
  - bool bTriedPasv;  
 
  -  
 
  - bool bTriedActive;  
 
  -  
 
  - wxString host;  
 
  -  
 
  - int port;  
 
  -  
 
  - };  
 
 
給它加個額外的變數,例如 bool bFtpAnywhere;然後,在List指令前,確定首先採用PASV或者PORT前,判斷 bFtpAnywhere是否為真,如果為真,那麼列表應該優先採用PORT模式,否則繼續執行預設的動作;而bFtpAnywhere的初始化應該從給伺服器發送 VDSI指令是否返回2XX來判斷,是否是一個FtpAnywhere伺服器,因為這裡涉及的修改太多,除非FileZilla代碼維護人員同意,否則沒有意義,因此,最簡單最快的方法還是直接登出我上面給出的代碼,雖然無法獲得100%相容,但是基本可以相容,而且通過設定項目,可以做到手動相容.
通過文章描寫和代碼的分析,我們可以清楚的知道:FileZilla是相容FtpAnywhere,希望對大家有用!