天天看點

silverlight中的socket程式設計注意事項

1.粘包

目前sl中的socket隻能用tcp/ip協定,而tcp/ip本質是一個"流"協定,也就是說資料無邊界,發送的就是一連串的位元組(沒有資料包的概念),是以連續發送時有所謂的“粘包”現象,詳細解釋如下:

比如你設定發送緩沖區的大小是512位元組,如果(在相隔時間極短的情況下)連續發送次資料,第一次為500位元組,第二次為100位元組,實際上你在伺服器端接收到的二次資料長度并不是500和100,而是512和88.

換言之:如果socket能“感覺”到馬上還有資料要發送,而且在本次發送的緩沖區還有空餘時,它會自動把下次發送的内容挪一部分過來,直到本次緩沖區填滿,以便有效的利用緩沖區,減少發送次數,至于它是如何感覺的,我就不知道鳥:)

是以如果想正确的劃清資料邊界,得自己想辦法封包/拆包

常見的解決辦法:在發送方與接收方制定一個共同的約定,比如定義一個結構體struct,把“包長度,包序号,要發送的資料,包的唯一辨別...”這一堆東西封裝在struct中,然後通過序列化最終得到一個byte[]進行發送。

另外如果最終得到的byte[]太大,超過了資料下标所允許的最大值(比如傳遞大檔案時),會導緻接收時反序列化失敗,是以還得人工把大塊頭資料割成一塊一塊,這裡有一個技巧:為了避免前面提到“scoket自我感覺良好”進行的資料挪移,分割的機關建議正好就是緩沖區的大小,如果不足一個緩沖區,甯可湊數填寫一些空位元組也要湊滿一個緩沖區長度--這樣系統會覺得你在高效使用緩沖區,沒有浪費,也就不會管閑事了 :)

2.異常捕獲

網絡程式設計中,會有各種不可控的情況,是以異常的捕獲很重要,否則程式會用着用着就挂掉了。

3.異常資料包的及時清理

異常資料包指“非法的”或“不完整的(比如一個大檔案最終拆分成10個包,結果第10個包都收到了,前面的某個包即始終收不到)”資料包,對于這類資料包,要及時清理否則會一直占用資源(必要時可以将連接配接關閉)

後話:很期待silverlight在未來的版本中,加入udp協定支援,這樣應用範圍将更加廣泛。

繼續閱讀