socket傳輸對象,這篇很失敗,請看BLOG中另外一篇

socket始終都只能傳遞byte數組,因爲TCP/IP協議的原因。

如果需要傳遞一個對象,那麼需要將這個對象序列化,然後就可以轉換成byte數組進行傳輸了。

目前我只能傳輸struct,並且每個成員變量都不能是很複雜的類型,比如List<>類型的就不可以了,因爲在獲取其非託管大小的時候會發生異常的。

在獲取非託管大小的時候不會發生異常的類型除了int、float、double、string等這些基本類型之外,還有array這種類型,其實int []、string []這些數組,都是繼承自array 的。

 

首先定義序列化struct

 

其次轉換對象爲byte []

 

接收端將接收到的數組轉換爲類型

  

 

socket接收的時候,接收端 :

recve是在接收的時候添加數據的,類型是List<Byte[]>,每次接收到一個buffer的內容,就往recve添加一個。

(代碼沒有經過多行的測試,只是recve.Count==1的情況通過,因爲我還沒有測試過太大的對象的傳輸)

 

另外關於 int bytesRead = handler.EndReceive(ar); 的理解:

bytesRead 爲0的情況是只有在對方close了socket之後。如果是大於0,說明對方還沒有close,有可能還有數據傳輸過來。如果是小於0,可能是有網絡異常,如果這句話直接異常,那麼情況就是,你仍然在監聽對方的消息,但是對方突然中斷了(非正常退出)。

其實EndReceive就是socket的receive的異步的阻塞語句。只有當socket的接收完畢或者接收數據超過你傳的buffer的大小之後,EndReceive纔會釋放阻塞,並且將得到的字節數量返回給bytesRead。

 

 using System.Runtime.InteropServices; 是 Marshal 的命名空間。

 

綜述:

以上的代碼實際上都是一無是處的,爲什麼?

如果是同一個進程中的通訊,你可以像上面那樣些,但是如果是不同進程之間的話,你可以試試,絕對不能通過。

 

原因就是託管的資源問題。

socket傳輸很簡單,我就不說了,而且也沒有什麼問題。

問題出現在轉換對象爲數組的時候,你建立的對象是一個託管對象,如果你沒有使用正確的序列化,那麼你得到的byte數組就是不正確的。

你將不正確的byte傳輸過去之後,再轉換,你能轉換成功嗎?顯然不能。

首先你要明白轉換序列化的意義在什麼地方。

轉換序列化,其實就是找到託管資源的實際數據,然後將這些實際的數據轉換爲byte,這樣轉換的話,就是對的。

如果你不使用序列化,那麼你的操作就是將託管資源轉換爲byte數組,那麼這樣轉換的東西就不是真正的你需要的,你將這樣的數據傳輸過去,是會引起不可預料的錯誤的。

 

具體這麼樣使用正確的序列化,有空的時候再研究吧。

發佈了22 篇原創文章 · 獲贊 7 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章