我有一些網絡代碼來處理任意TCP連接。.NET NetworkStream讀取緩慢
這一切似乎按預期工作,但似乎緩慢。當我對代碼進行剖析時,似乎在NetworkStream.Read()中花費了600毫秒,我想知道如何改進它。我已經調整了緩衝區大小,並在一個龐大的緩衝區之間交替讀取,以便一次讀取所有數據,或者將數據連接成一個StringBuilder。目前我使用的客戶端是一個網頁瀏覽器,但是這個代碼是通用的,它可能不是被髮送給它的HTTP數據。有任何想法嗎?
我的代碼是這樣的:
public void StartListening()
{
try
{
lock (oSyncRoot)
{
oTCPListener = new TcpListener(oIPaddress, nPort);
// fire up the server
oTCPListener.Start();
// set listening bit
bIsListening = true;
}
// Enter the listening loop.
do
{
// Wait for connection
TcpClient newClient = oTCPListener.AcceptTcpClient();
// queue a request to take care of the client
oThreadPool.QueueUserWorkItem(new WaitCallback(ProcessConnection), newClient);
}
while (bIsListening);
}
catch (SocketException se)
{
Logger.Write(new TCPLogEntry("SocketException: " + se.ToString()));
}
finally
{
// shut it down
StopListening();
}
}
private void ProcessConnection(object oClient)
{
TcpClient oTCPClient = (TcpClient)oClient;
try
{
byte[] abBuffer = new byte[1024];
StringBuilder sbReceivedData = new StringBuilder();
using (NetworkStream oNetworkStream = oTCPClient.GetStream())
{
// set initial read timeout to nInitialTimeoutMS to allow for connection
oNetworkStream.ReadTimeout = nInitialTimeoutMS;
int nBytesRead = 0;
do
{
try
{
bool bDataAvailable = oNetworkStream.DataAvailable;
while (!bDataAvailable)
{
Thread.Sleep(5);
bDataAvailable = oNetworkStream.DataAvailable;
}
nBytesRead = oNetworkStream.Read(abBuffer, 0, abBuffer.Length);
if (nBytesRead > 0)
{
// Translate data bytes to an ASCII string and append
sbReceivedData.Append(Encoding.UTF8.GetString(abBuffer, 0, nBytesRead));
// decrease read timeout to nReadTimeoutMS second now that data is coming in
oNetworkStream.ReadTimeout = nReadTimeoutMS;
}
}
catch (IOException)
{
// read timed out, all data has been retrieved
nBytesRead = 0;
}
}
while (nBytesRead > 0);
//send the data to the callback and get the response back
byte[] abResponse = oClientHandlerDelegate(sbReceivedData.ToString(), oTCPClient);
if (abResponse != null)
{
oNetworkStream.Write(abResponse, 0, abResponse.Length);
oNetworkStream.Flush();
}
}
}
catch (Exception e)
{
Logger.Write(new TCPLogEntry("Caught Exception " + e.StackTrace));
}
finally
{
// stop talking to client
if (oTCPClient != null)
{
oTCPClient.Close();
}
}
}
編輯:我得到大致在兩個完全獨立的機器(我的XP開發機,並在科羅拉多州一個2003箱)相同的數字。我已經把一些時間到相關的部分(使用System.Diagnostic.StopWatch)周圍的代碼,並將其轉儲到日誌:
7/6/2009 3:44:50 PM : Debug : While DataAvailable took 0 ms 7/6/2009 3:44:50 PM : Debug : Read took 531 ms 7/6/2009 3:44:50 PM : Debug : ProcessConnection took 577 ms
我遇到了同樣的問題。我在這篇文章中看到了你的解決方案,但是nReadTimeOutMS和bTurboMode如何?你能給我一個完整的描述嗎?如果你和我分享這個課程,我非常感興趣並且很感激。提前致謝。 – olidev 2011-06-08 12:49:44
我的實現是非常基本的,我在這篇文章之後重新編寫了一大部分,以便正確執行。問題的關鍵在於,如果發送客戶端不告訴你有多少數據正在發送,你只能依靠超時等。我最近的實現檢查了標題,看看有多少數據正在發送,以及它何時讀取了我停止閱讀的所有內容。 – 2011-06-09 08:47:35