2014-03-03 12 views
0

我決定在C#中自己推出FTP套接字客戶端以獲得更多控制權,但主要是爲了學習體驗。但是我不知道在發出RETR命令後需要讀取多少文件數據。我能夠建立初始FTP通信連接,然後通過發出PASV命令和所有好東西來連接新端口上的第二個套接字。如何確定在FTP服務器上使用RETR時文件的結尾(PASV)

我的問題是,當我在通信端口上發出RETR命令時,FTP服務器開始通過被動端口發送文件,然後在通信端口上完成發送時發出226命令。我可以很好地接收數據,但有時在所有文件數據到達被動端口之前,226命令到達通信端口。所以,如果我在收到226命令後立即指示我的被動套接字任務停止讀取,它有時會錯過包含文件結尾的數據。我已經嘗試在退出Socket.Receive循環之前檢查Socket.Available,但通常情況下,Socket.Available將報告套接字上可用的0字節,但套接字並不意味着沒有更多的數據辦法。讀取FTP規範似乎FTP服務器應該在完成發送所有數據後關閉數據連接,但我認爲不會發生這種情況。我可以整天讀取0字節的數據。我正在查看一個破損的FTP服務器,還是我在我的方法中做錯了什麼?

現在的一些額外的信息可能是我的問題的答案。使用連接到同一FTP服務器的Filezilla,我發現當請求文件時,FTP服務器將文件長度附加到括號中的150命令。例如,「150打開test.zip的BINARY模式數據連接(123421字節)」。這個文本是FTP標準的一部分嗎?如果所有FTP服務器都使用這種相同的行爲和格式,那麼我可以繼續閱讀,直到我達到123,421字節。但是,如果這不是普通的行爲,那麼我就回到原點了。欣賞任何想法。

回答

0

看來我沒有很好地閱讀規範,因爲RFC 3659中有一個SIZE命令會返回文件的大小。我測試了它,它會做我所需要的。

+0

並非所有的服務器都支持'SIZE',因爲直到[RFC 3659](https://tools.ietf.org/html/rfc3659)才被標準化。爲了簡單檢測EOF,傳輸模式本身足以告訴您傳輸何時完成。參見[RFC 959](https://tools.ietf.org/html/rfc959)第3.4節。在STREAM模式下(通常情況下),文件末尾由關閉數據套接字的發件人表示(並且是的,服務器將在檢索時關閉套接字,因此您必須確保正確檢測到該關閉)。在BLOCK模式下,數據以塊的形式發送,並且在傳輸結束時會有一個EOF塊。 –

0

我找不到在發出RETR命令後需要讀取多少文件數據。

這取決於傳輸模式(參見RFC 959第3.4節)。

在STREAM模式下(通常情況下),文件的結尾由關閉數據套接字的發件人表示。這意味着數據連接不能用於多次傳輸。

在BLOCK模式下,數據以塊的形式發送,並且發送者將在傳輸結束時發送EOF塊。這使得數據連接可以重複用於多次傳輸。

我的問題是,當我在通信端口上發出RETR命令時,FTP服務器開始通過被動端口發送文件,然後在通信端口上完成發送時發出226命令。我可以很好地接收數據,但有時在所有文件數據到達被動端口之前,226命令到達通信端口。

只有在完成讀取傳輸端口上的數據之後,才能讀取通信端口上的響應。因此,如果我立即發信號通知被動套接字任務在獲得226命令後停止讀取,它有時會錯過包含文件末尾的數據。

所以不要指示您的套接字停止閱讀。讓它停止閱讀。

我試過檢查Socket.Available退出了我的Socket.Receive循環,但往往不是Socket.Available將報告插座上但,這並不意味着有ISN插座可用0字節之前路上有更多數據。

正確。 Available只是報告當時有多少字節正在等待讀取。只要繼續閱讀,直到Receive()告訴您實際發生斷開連接。如果您想在調用Receive()之前輪詢套接字狀態,請使用Poll(),斷開連接將報告爲可讀狀態。無論哪種方式,Receive()將在正常的斷開連接上返回0字節,並在異常斷開連接上拋出異常。

讀FTP符合規範卻彷彿FTP服務器應該關閉數據連接發送完所有的數據

流模式後,是的。

但我不認爲這種情況正在發生。

是的。

我可以一直保持循環讀取0字節的數據。我正在查看一個破損的FTP服務器,還是我在我的方法中做錯了什麼?

您在方法學中做錯了什麼。

使用連接到同一FTP服務器的Filezilla,我發現當請求一個文件時,FTP服務器將文件長度附加到括號中的150命令。例如,「150打開test.zip的BINARY模式數據連接(123421字節)」。這個文本是FTP標準的一部分嗎?不,它不是。文本是任意的,它可以是服務器想要的任何東西。重要的是響應代碼(150)來表明轉移正在進行。

如果所有FTP服務器使用相同的行爲和格式

他們不使用相同的文本格式。

然後我可以繼續閱讀,直到我打123,421字節。

您應該繼續閱讀,直到服務器關閉數據連接。然後讀取通信端口上的最終響應,以確保服務器認爲傳輸成功,並且不會過早中止。

相關問題