最近一個多月一直在弄文件傳輸的組件。最近也有個基本的樣子了,這里算是一個簡單總結吧。
文件傳輸底層使用開源的c++通信組件hp-socket(Pullserver,pullClient)。感興趣的可以搜一下。
廢話不多說,進入正題
首先,所有的客戶端必須首先登陸服務器,在服務器進行注冊,在服務器端維護一個客戶端標識與客戶端信息的映射關系,比如客戶端信息類ClientInfo。
//代碼片段ClientInfo{ IntPtr connID; string ip; ushort port;}則服務端,就需要有這樣一個類似Dictionary<string,ClientInfo>的字典。在客戶端A給客戶端B轉發數據的時候,可以從這個映射關系中找到對方。
登錄過程

在客戶端登錄成功后,就可以發送文件了。

包頭信息說明
TransferId:傳輸id,標識在同時傳輸多個文件時,是不同的傳輸。
TransferType:傳輸類型
TransferCommand:傳輸命令
md5:檢驗值(md5或者hash,越短越好,算法越快越好)
FileName:文件名。
FileRelativePath:傳輸文件夾時用到,文件夾中的文件,需要用到相對路徑,接收端根據接收路徑+相對路徑進行保存文件夾中的文件。
Size:文件或者文件夾總大小,將總大小拋給應用層,計算傳輸速度。
currendIndex:當前傳輸包的索引,也是讀取文件第幾個包的索引。
PkgCount:總共多少個包。接收端可以根據當前索引和包總數,來判斷是否傳輸完成,或者在斷點續傳的時候用到。
From:發送端標識
To:接收端標識
BodySize:每次傳輸的body大小。
自定義協議
固定包頭+Body
每次包都要遵循該協議,服務器收到包后,要進行解析,根據包頭中bodysize取出這次的數據Data。
斷點續傳
在接收端,每次接收到包,寫入文件的同時,將包頭信息寫入本地文件(ini也好,xml文件也好)。然后發送端,再次發送該文件的時候,首先會發送請求包,接收端根據該文件的包頭信息和ini文件中的信息,比對md5是否相同,發送方是否相同,如果相同,則將CurrentIndex+1,響應給發送端。發送端就可以直接從CurrendIndex+1的位置繼續讀取文件包進行發送。
該組件前前后后大概一個多月,里面業務比較復雜,需要考慮的到的東西還是比較多的,目前實現,同時傳輸多個文件,多個文件夾,斷點續傳功能。但多文件和多文件夾同時混合發送仍有問題。還有客戶端A給客戶端B發送文件的同時,客戶端B給客戶端A發送,仍有問題。
通過該組件的設計,也收獲不小,對業務能力也是一種考驗。對tcp通信有了更深入的學習。
本文只是分享一下思路,感興趣的可以搜一下hp-socket。
新聞熱點
疑難解答