2014-02-20 41 views
0

這裏是我的發送數據的方法:如何使用StreamWriter發送byte []?

// this method serializes an object and is returned as a string (Base64 encoded) 
    public void Send(Packet packetData) 
    { 
     try 
     { 
      StreamWriter w = new StreamWriter(cli.GetStream()); 
      string s = SerializeObject(packetData); 
      w.WriteLine(s + "\n"); 
      w.Flush(); 
     } 
     catch (ObjectDisposedException) { ShutdownClient(-2); } 
    } 
  • CLI是的TcpClient對象
  • 包是一個序列化對象

這是我收到的方法:

private string GetMessage(StreamReader r) 
    { 
     try 
     { 
      string s = r.ReadLine(); 
      s = s.Replace(" ", ""); 

      // this string is returned and then deserialized 
      return s; 
     } 
     catch (Exception e) { System.Windows.Forms.MessageBox.Show(e.Message); return null; } 
    } 

當我使用它,50%的時間工作。如果它不起作用,這是因爲: 「輸入流不是有效的二進制格式。起始內容(以字節爲單位)爲:6D-2E-44-72-61-77-69-6E- 67-2E-43-6F-6C-6F-72-0F-00 ......」

我已經更換Base64編碼的使用Encoding.Default.GetString/GetBytes會嘗試,但後來我得到這個: 「Binary stream'0'不包含有效的BinaryHeader,可能的原因是序列化和反序列化之間的流或對象版本無效。」 如果我打印出此(默認編碼)字符串的長度,它是183.但是,如果我打印出實際的字符串,則不會打印任何內容。

我還可以通過StreamWriter作爲字符串發送一個字節[]嗎?

+0

使用'streamWriter.BaseStream.Write'-方法 –

+0

您是否嘗試過在兩端使用特定編碼?如UTF8或ASCII? –

+0

另外你爲什麼要從你的getter中刪除流中的字符? –

回答

2

我還能如何發送一個字節[]作爲一個字符串

不,當字符串是標準化的字節[]的內容將被損壞,你現在做的方式。一個字符串應該只用於存儲Unicode字符。並非每個Unicode碼點都是有效的。

如果使用字符串是至關重要的,那麼你應該在發送端使用Convert.ToBase64String(),在接收端使用Convert.FromBase64String()。

請記住,TCP完全能夠傳輸二進制數據。你可能會陷入這個漏洞,因爲TCP實現了一個,它不會做任何事情來幫助你傳輸消息。傳輸二進制「消息」的簡單方法是首先寫入字節長度[]。接收機首先讀取該長度,然後知道應該傳遞給Read()調用以從TCP流中恢復字節[]。

+0

謝謝你的解釋。我這樣做,但有時讀取的數據量比它應該少2或3個字節,爲什麼會發生? – Daaksin

+0

當您計算每個字節時,您不能讀取「less」。忽略Read()的返回值是一個標準錯誤。 –

+0

你確定嗎?下面是閱讀的日誌: – Daaksin