2012-08-07 128 views
1

我正在編寫一個庫來簡化我在未來項目中的網絡編程。我希望它能夠強健有效,因爲這將在我將來的所有項目中得到應用。 (順便說一句,服務器和客戶端都將使用我的庫,所以我沒有假設我的問題是一個協議)我正在寫一個函數接收來自網絡流的字符串,我使用31個字節的緩衝區和一個用於標記。標記值將指示哪個字節是EOF。這裏是我的代碼供您使用或審查...C#網絡流getString方法

public string getString() 
    { 
     string returnme = ""; 
     while (true) 
     { 
      int[] buff = new int[32]; 
      for (int i = 0; i < 32; i++) 
      { 
       buff[i] = ns.ReadByte(); 
      } 
      if (buff[31] > 31) { /*throw some error*/} 
      for (int i = 0; i < buff[31]; i++) 
      { 
       returnme += (char)buff[i]; 
      } 
      if (buff[31] != 31) 
      { 
       break; 
      } 
     } 
     return returnme; 
    } 

編輯︰這是最好的(高效,實用等)來完成我在做什麼。

+0

我沒有問題,你能否提供更多信息。 – user854301 2012-08-07 05:32:30

+1

您正在使用31個整數..不是字節。另外..你的問題是什麼? – 2012-08-07 05:35:09

回答

3

這是最好的(高效,實用等)來完成我在做什麼。

號首先,你是限制自己的字符在0-255碼點範圍,而不夠;其次:序列化的字符串是一個解決的問題。只需使用一個Encoding,通常是UTF-8。作爲網絡流的一部分,這可能意味着「編碼長度,編碼數據」和「讀取長度,緩衝大量數據,解碼數據」。另外請注意:如果ReadByte()返回負值,那麼您沒有正確處理EOF場景。

作爲一個小的推論,請注意,在循環中附加到string永遠不是一個好主意;如果你的確如此這樣做,使用StringBuilder。但不這樣做。我的代碼將更多的東西一樣(嘿,whadya知道,這裏是從protobuf網,簡化了一下我的實際串讀取代碼):

// read the length   
int bytes = (int)ReadUInt32Variant(false); 
if (bytes == 0) return ""; 

// buffer that much data 
if (available < bytes) Ensure(bytes, true); 

// read the string 
string s = encoding.GetString(ioBuffer, ioIndex, bytes); 

// update the internal buffer data 
available -= bytes; 
position += bytes; 
ioIndex += bytes; 
return s; 

最後一點,我想說:如果您要發送結構化的消息,認真考慮使用專門處理這些東西的預滾動序列化API。例如,你可以那麼就這樣做:

var msg = new MyMessage { Name = "abc", Value = 123, IsMagic = true }; 
Serializer.SerializeWithLengthPrefix(networkStream, msg); 

,並在另一端:

var msg = Serializer.DeserializeWithLengthPrefix<MyMessage>(networkStream); 
Console.WriteLine(msg.Name); // etc 

完成任務。

+0

我是一個小新手,你可以編輯你的答案的評論來解釋較不抽象 – David 2012-08-07 06:02:22

+0

@ user1580785哪個位是抽象的?樂於幫助,但需要更清楚。有關信息,0-255限制,不處理EOF和string-append的問題不是抽象的:它們是真正的問題。 – 2012-08-07 06:13:23

+0

幾次重新讀取代碼(非序列化)之後,它們都開始單擊免除「確保」和「更新內部緩衝區數據」。我猜這是針對已經放入緩衝區的數據,但如果您可以添加一些假設的代碼來幫助實現這一點,我很難 – David 2012-08-07 06:18:55

0

我認爲tou應該使用具有固定大小的StringBuilder對象以獲得更好的性能。

+0

爲什麼要固定大小? – 2012-08-07 05:57:01