上一篇文章五、Socket之UDP異步傳輸文件-實現傳輸中取消傳送中,還遺留了一個傳輸文件最大的問題,就是傳輸過程中丟包,這樣在文件傳輸過程中就會卡住了,這篇文章就來解決文件傳輸中的丟包問題,實現穩定的文件傳輸。
檢測丟包是一個很麻煩的問題,解決的方法可能也有不少,我采用的是在接受文件端來檢測,當開始接收文件,收到一個數據包后,如果等待超過了一定時間后都沒有收到數據包,就給發送方發送一個新的請求,要求繼續發送文件,直到文件全部接收完成。具體的做法就是:
1、 在ReceiveFileManager類中加入一個記錄文件分塊接收狀態的列表Dictionary<int, bool>,int表示文件分塊的序號,bool表示是否已經接收,初始化為全部沒有接受(false)。
2、 在ReceiveFileManager類中加入一個Timer,用來檢測收到一個包后,等待的時間是否超過了設置的值,超過就給發送方發送數據包,請求繼續發送文件,需要發送的文件塊序號為從Dictionary<int, bool>中查詢出來的沒有接收的文件塊序號。
3、 如果Dictionary<int, bool>中的所有文件塊已經收到(全部為true),文件就接收完成了。
按照以上的做法,就可以保證文件可以全部接收到了。其實也可以從發送方來處理這個問題,就是發送方發送一個包后,如果等待了一定時間沒有接收到接受方的回復,就重發這個包,也許有時間,下次就換這種方式看看,大家也可以自己試試。具體的實現還是挺麻煩的,大家從源碼中看吧。
在新的例子中,用了新寫完的文件傳輸控件,外觀漂亮了,控件的顯示效率也提高了不少。
到現在為止,基本上實現了一個穩定的異步UDP(Socket)發送多文件的功能了,在實現中是通過MD5做文件校驗的,當文件很大的時候,計算MD5比較慢,所以就感覺發送的時候有點卡,其實很多時候是不需要的(QQ傳文件也沒有驗證的),我們可以把這個功能取消掉,用一個GUID來標識每一個不同的文件就行了。
下面來看看傳輸文件的截圖:
