2010-03-15 84 views
3

我正在爲通常以500或更少字節的字符串形式發送數據的服務器編寫客戶端。但是,數據偶爾會超過該數據,並且一組數據可能包含200,000個字節,對於所有客戶端都知道(初始化或重要事件)。但是,我想不必讓每個客戶端都運行一個50 MB的套接字緩衝區(如果甚至可能的話)。我應該如何處理不完整的數據包緩衝區?

每組數據都由空字符\0定界。我應該查看哪種結構來存儲部分發送的數據集?

例如,服務器可能會發送ABCDEFGHIJKLMNOPQRSTUV\0WXYZ\0123!\0。我想單獨處理ABCDEFGHIJKLMNOPQRSTUVWXYZ123!。此外,服務器可以發送ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890LOL123HAHATHISISREALLYLONG而不包含終止字符。我希望這個數據集存儲在某個地方,以便以後添加和處理。

另外,如果有問題,我正在使用異步套接字方法(BeginSendEndSend,BeginReceive,EndReceive)。

目前我在List<Byte>StringBuilder之間辯論。對這兩種情況進行比較將會非常有幫助。

回答

2

你可以只使用一個List<byte>作爲緩衝,因此在.NET框架的需要根據需要自動擴展照顧它。當您找到一個空終止符時,您可以使用List.RemoveRange()從緩衝區中刪除該消息並將其傳遞到下一層。

你可能想添加一個檢查,如果超過一定的長度拋出一個異常,而不僅僅是等待,直到客戶端運行內存不足。 (這與Ben S的答案非常相似,但我認爲在編碼問題上,一個字節數組比StringBuilder更健壯一點。解碼字節到字符串最好做得更高,一旦你有一個字符串完整的信息。)

+0

也許是'MemoryStream',而不是'List '?和'stream.Seek(0,SeekOrigin.Begin)'而不是'RemoveRange'。 – 2010-03-15 03:28:54

+0

這也是一種可能性。我想這取決於代碼的結構。如果遇到空終止符,它立即處理消息,則尋找0將正常工作。但是,如果它先讀取所有待處理的套接字數據,然後查找空終止符,則在第一條消息後尋求0將失去所有內容。我假設後者。 – EMP 2010-03-15 06:23:11

4

將套接字中的數據讀入緩衝區。當你得到終止字符時,把它變成一條消息,並把它發送到你的代碼的其餘部分。

此外,請記住TCP是,而不是數據包。所以你永遠不要以爲你一次只能讀一次就能得到所有的東西。

就緩衝區而言,您應該最多隻需要每個連接一個。我可能會用最大的尺寸,你合理指望得到啓動,如果填充,創建一個更大尺寸的新緩衝區 - 一個典型的策略是,當您用完,避免了太多的攪動的規模擴大一倍分配。

如果您有多個傳入連接,您可能需要執行一些操作,例如創建一個緩衝池,並在完成這些操作時將大「池」返回到池中。

1

我只想用一個StringBuilder並一次,複製和排空建設者在一個字符讀每當我打了一個空終止符。

+0

這就是我的想法,但我擔心這會成爲一個效率殺手。 – 2010-03-15 01:12:40

+0

它不應該是,它被設計爲有效地處理追加任意字符串。 – 2010-03-15 01:16:04