2014-04-08 43 views
2

我已經開始使用C#學習TCP網絡。我遵循各種教程,查看了示例代碼,並通過異步連接和寫入/讀取來運行TCP服務器和客戶端。我也有文件傳輸工作。跟蹤文件傳輸百分比

現在我希望能夠跟蹤服務器和客戶端的傳輸進度(0% - > 100%)。當啓動從服務器到客戶端的傳輸時,我發送期望的文件大小,所以客戶端知道需要多少字節,所以我想我可以很容易地做到:curCount/totalCount在客戶端上。但是我對如何爲服務器做這件事感到困惑。

服務器如何準確地告訴客戶端的轉移情況?我應該根據服務器自身的狀態(通過networkStream.BeginWrite()回調,還是通過從磁盤和網絡寫入的塊加載)猜測?還是應該讓客戶端繼電器回到客戶端完成的服務器?

我想知道什麼時候關閉連接,以及能夠直觀地顯示進度。服務器是否應該信任客戶端關閉連接(禁止網絡錯誤/超時/等)?或者服務器可以在寫入流時立即關閉連接?

+0

只要完成將所有字節寫入流,服務器就可以安全地關閉連接。您永遠不會確切地知道客戶端的狀態來自服務器端,而不會對文件傳輸造成負面影響,但您可以跟蹤發送的百分比。 – itsme86

+0

好吧,我想這可能是它的樣子。謝謝。 – user42524

回答

0

這裏有兩個截然不同的完成百分比:客戶端和服務器。如果您認爲服務器在發送最後一個字節時完成,則服務器的百分比將始終至少與客戶端的百分比一樣高。如果您認爲服務器在客戶端處理完最後一個字節時完成,則服務器的百分比將滯後於客戶端的一個百分比。無論你做什麼,你的兩端都會有不同的價值觀。

這些值將因服務器應用程序和客戶端應用程序之間各種緩衝區當前排隊的數據量而有所不同。這個緩衝區空間通常很小。 AFAIK最大TCP窗口大小默認是200ms的數據傳輸。

也許,您根本不必擔心這個問題,因爲雙方的進度值將會彼此緊密相關。

我應該根據服務器自身的狀態(通過networkStream.BeginWrite()回調,或者通過從磁盤和網絡寫入的塊加載)來猜測嗎?

這是一個適當的解決方案。

或者我應該讓客戶端中繼回到服務器客戶端完成?

這將是我在第一段中描述的第二種情況。也可以接受,但不一定是更好的結果和更多的開銷。我無法想象現在我會這樣做的一種情況。

服務器是否應該信任客戶端關閉連接(禁止網絡錯誤/超時/等)?

當TCP交換的一方完成發送時,應關閉發送套接字(使用Socket.Shutdown(Send))。這會導致另一方讀取零字節並知道傳輸已完成。

關閉套接字之前,應關閉它。如果Shutdown呼叫完成而沒有錯誤,則保證遠程方已收到所有數據並且本地方已收到所有數據。

或者服務器一旦寫入流就可以關閉連接嗎?

首先,關閉,然後關閉。單獨結束並不意味着成功轉移。

+0

好的。如果我想連續發送2個或更多文件,那麼呢?我應該使用相同的流,並在文件之間進行區分嗎?還是應該在創建新流之前關閉並關閉現有的設備? – user42524

+0

重複使用相同的連接可節省您傳輸的每個文件的一些開銷。如果你傳輸很少的大文件,你選擇哪一個並不重要。所以選擇對您更爲方便的方法。如果你傳輸1米1字節的文件,你應該重新使用連接。 – usr

+0

@文件之間user42524相反的分界,我會第一個文件之前發送一些元數據(文件數,每個文件大小),以幫助客戶在跟蹤完成百分比的每個文件。 – itsme86