上一篇文章說明了如何用UDP多播實現屏幕廣播,用這種方式可以大大減少數據傳輸量,但是現在還有一個問題:由於UDP數據包的大小有限制,所以如果要傳輸一張圖片需要把圖片划分成若干個部分分開發送,但是UDP是屬於不可靠的傳輸,它並不能保證這些數據包可以順序到達接收方,傳輸過程中可能會出現丟包或亂序的情況,導致接收方不能接收到完整圖片,在網上搜索的用UDP可靠傳輸的方法大多數都是接收方在接收出現問題的時候向發送方請求重新發送,但這種解決方案顯然不實用於屏幕廣播這種一對多的傳輸模式。最后在CSDN上找到了一種解決方法,這里簡要說明一下思路。(CSDN地址:http://download.csdn.net/detail/ztxzyr/3824829)
這里要用到一種UDP數據包的數據結構,這里給出我自己的定義:
#define MAXBUFSIZE (32 * 1024) //緩沖區最大值 //UDP數據包 typedef struct _UDPPACKAGE{ DWORD dwIndex; //當前包序號 DWORD dwTotalSize; //數據總大小 bool bFinish; //是否已結束 char buf[MAXBUFSIZE]; //數據緩沖區 DWORD dwDataSize; //緩沖區數據大小 }UDPPACKAGE, *PUDPPACKAGE;
這里假設要傳送的圖片大小是128KB,由於數據包中數據緩沖區大小是32KB,所以要分成4個udp包,它們的序號依次是0、1、2、3,前三個數據包的bFinish設置為false,最后一個bFinish設置為true。發送方采用以上這種數據結構把數據打包發送出去。剩下的工作由接收方負責。
接收方接收數據的方法如下:首先設置一個當前期望收到的數據包序號dwCurrentIndex,當第一次接收時由於之前從未接收過圖片,所以設置為0,表示希望收到序號是0的序號,當收到一個數據包的時候判斷該包的序號與期望收到的序號是否相等,如果相等,就把這個包的數據寫入文件,並且使dwCurrentIndex加1,然后判斷這個包是不是最后一個包,即bFinish是否為真,如果為真則文件接收完畢,否則繼續接收;如果不相等的話,就把dwCurrentIndex設置為0,同時把文件指針移動到文件開始處,表示下一個希望收到圖片的第一個包,上一張圖片剩余的包已不再有效。具體流程如下:
整個接收過程用一句話來說就是:接收方只接收按序到達的圖片,不按順序來的都不處理。因為發送方是不斷發送圖片,所以有一張或幾張圖片沒有接收不會造成太大影響,這樣接收圖片不完整的問題也就可以解決了。