天天看點

在silverlight中利用socket發送圖檔或檔案

silverlight中的socket通訊支援,讓sl開發基于web的聊天工具成為了可能,後來OpenFileDialog,SaveFileDialog的出現,更使得邊聊天邊傳送圖檔(檔案)得以實作,最新的SL4中又加入了攝像頭支援,也許不久真的可以用silverlight開發出功能強大的視訊聊天系統,目前唯一還沒有解決的是p2p問題,根據sl3的sdk文檔所述: 

Socket 類為網絡通信提供了一組方法和屬性。Socket 類允許您使用 ProtocolType 枚舉中所列出的任何一種通信協定執行異步資料傳輸。目前,Silverlight 上唯一支援的 ProtocolType 是 TCP 協定 (Tcp)。

關于在 Silverlight 中使用套接字的一個限制是:網絡應用程式可以連接配接到的端口範圍必須在 4502-4534 範圍内。這些是使用套接字從 Silverlight 應用程式進行連接配接所唯一允許使用的端口。如果連接配接的目标端口不在此端口範圍内,則嘗試連接配接時将會失敗。 

silverlight中的socket使用的協定目前隻有tcp協定,不知道以後會不會增加其它協定。

在silverlight中利用socket發送圖檔或檔案

簡單點說,我們需要處理三方面的東西:

1.服務端上的政策請求監聽(943端口):用于接受silverlight socket用戶端首次連接配接時自動發起的政策請求

2.服務端上的消息資料監聽(4502至4534範圍中的某一個端口):用于接受socket用戶端發送過來的使用者資料,并根據實際需要轉發(或不處理)

3.silverlight用戶端的服務端連接配接,向服務端發資料,異步接受服務端資料...等

在silverlight中利用socket發送圖檔或檔案

要點:

1.如何判斷發過來的資料(byte數組),是文本還是圖檔?或是檔案?

我用了一個比較原始的辦法,在byte數組中前後加入了一些特定字元,類似字元串的分隔符,接收完以後,再根據特定字元拆分,然後根據其中的标記位(開發人員可自定義)來确定格式

2.發送時,檔案或圖檔如何轉化為byte數組?

OpenFileDialog可以将選擇後的檔案傳回一個流,再利用BinaryReader将檔案流轉化為數組

3.接受時,如何将byte數組還原為檔案(或圖檔),并儲存?

利用MemoryStream.write将byte數組變成流,然後再調用bitmap.SetSource設定源,進而得到圖檔;至于檔案儲存,SaveFileDialog确定儲存的檔案名後,也會傳回一個流,将接受到的byte數組轉化為流,然後儲存即可

4.發送的資料如果超過緩沖區大小,一次不能接受完整如何處理?

發送時,前後加上特定字元做為标記位,第一個接收到的字元為特定字元則認為是資料包的開始,如果最後一個字元不是特定字元,說明未接收完整,則繼續循環接收,直到最後一個字元遇到特定字元為止。

問題:

圖檔或檔案通過流轉化為byte數組後,如果數組本身就包含分隔字元,會導緻收到資料後“解碼”失敗,是以在發送前,我把圖檔或檔案數組中的分隔符替換成其它字元了,但這樣會導緻還原時圖檔失真。(2009-11-30更新:關于這個問題的解決辦法,事後想了下,問題的出現是由于分隔符重複引起的,可以換一種思路,比如在byte前端明确标注該資料包的長度,類似 ^512^...後面是發送的内容(這裡的内容可以是自己定義的複雜對象,利用序列化最終轉化為byte[]),這樣接受到第一個"^"時認為是開始,第一個與第二個"^"之間的數字即為後面内容流的長度,理論上應該可行)

源代碼下載下傳:http://files.cnblogs.com/yjmyzz/SocketChat.rar

調試方法:

1.先啟動解決方案中的Server

2.再啟動silverlight項目Client

3.測試圖檔或檔案發送時,我在源代碼根目錄下特意放了一張小圖檔(test.png)及一個小檔案檔案(test.txt),友善大家調試

更新:

[2009-11-29]

1.将原來的政策監聽與消息監聽合二為一,在同一個程式中開了二個線程分别監聽

2.解決資料包超過緩沖區大小時的接收問題

3.簡化代碼,去掉原來的線程排程,改用循環調用實作

4.界面做了微調,更容易操作

[2009-12-2]

[2009-12-16]

轉載請注明來自菩提樹下的楊過