2016-10-03 50 views
0

我寫了一個VB.Net應用程序,它連接到一個遠程IP /端口組合,輸出穩定的消息流。 IP地址可以是本地主機,也可以是遠程機器。在套接字上接收數據的最有效的方法

遠程進程可以在任何時候停止和啓動,我的進程需要連接到它並簡單地開始接收。兩者之間沒有談判使用哪個端口。

我現在的代碼使用TcpClient和NetworkStream一次讀取一個字節。它被轉換爲相應的ASCII字符(所有的信息都是ASCII文本),並被附加到一個字符串中,直到收到一個EOL字符。一旦該行被添加到要處理的隊列中,字符串將被截斷並且該過程再次開始。在這種情況下,一次聽一個字節可能不是最有效的方法。

我現在正在測試應用程序,並遇到一些嚴重的性能問題。雖然我當前的代碼有效,但它無法處理拋出的數據量。雖然它每秒可以處理500條消息,但實際上它在每秒1500次的速度下掙扎,並在20%的CPU處達到峯值。

我確定瓶頸是每次讀取一個字節的數據 - 有沒有辦法加快速度?理想情況下,我希望一次讀入一行數據,直到收到EOL字符,但這種能力似乎不存在於TcpClient中。

套接字編程不是我的強項,所以也許我錯過了一些明顯的東西。幫幫我 !

+0

我會說通過TCP進行通信的最佳方式是實現[** message framing **](http://stackoverflow.com/a/37352525/3740093),但如果您希望它適合您當前模型,你也可以使用[**'StreamReader' **](https://msdn.microsoft.com/en-us/library/system.io.streamreader(v = vs.110).aspx)。 - 請記住,通過實施消息框架,您將同時實施一種識別不同種類數據(例如文本,圖像,文件等)的方法。 –

+0

這些消息是可變長度的,所以我看不到消息幀如何工作 - 它們只是純文本,沒有花哨的編碼。除非我錯了(我可能是)不是StreamReader綁定到本地文件而不是套接字? –

+0

'StreamReader'是**流_reader _ **。它具有從其他流中讀取文本的功能。要引用文檔,StreamReader _「以特定編碼從字節流中讀取字符」。_請參閱[**其構造函數之一**](https://msdn.microsoft.com/zh-cn/library/ yhfzs7at(v = vs.110)的.aspx)。 - 「這些消息是可變長度的,所以我不能看到消息框架如何工作 - 它們只是純文本,沒有花哨的編碼。」 - 我不明白。 「變長」是什麼意思?另外,如果他們不使用任何編碼,你怎麼發送它們? –

回答

-2

嘗試使用System.Text命名空間中的ASCIIEncoding.GetString方法。它應該將一個字節數組轉換爲一個字符串,而不是一次一個字節。

Dim ascii As New ASCIIEncoding() 
'*** define bytes() byte array here *** 
Dim decoded As String = ascii.GetString(bytes) 

此方法還有一個unicode變體。

+0

這會如何幫助他?如果他一次只得到一個字節,他就回到他開始的地方。如果他一次獲取多個字節,他可能在緩衝區中有兩個消息位。 –

0

Bytewise IO通常在教程中顯示,因爲它非常容易。它不適合生產。

當編程套接字使用最高級別的抽象,你可以。理想情況下,您放棄原始套接字並通過諸如HTTP或websockets之類的內容請求數據。可用的庫。

如果你堅持使用原始套接字,你可以嘗試一個基於行的格式,使用StreamReader/Writer。不需要ASCII,只需使用UTF8這是默認值。

讀者可以通過類似的方式獲得:new StreamReader(new NetworkStream(socket))

相關問題