У меня есть код сети для обработки произвольного TCP-соединения..NET NetworkStream Чтение медленности
Все, кажется, работает должным образом, но кажется медленным. Когда я профилировал код, он, кажется, потратил хорошие 600 мс в NetworkStream.Read(), и мне интересно, как его улучшить. Я искал размеры буфера и чередовался между массивным буфером для чтения всех данных за один раз или небольшой, который должен объединить данные в 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();
}
}
}
Edit: я получаю примерно те же цифры на двух совершенно отдельных машинах (мою машину развития 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
Моя реализация была очень простой, я переписал большой кусок ее после этого сообщения, чтобы сделать это правильно. Суть в том, что вы полагаетесь только на таймауты и т. Д., Если отправляющий клиент не сообщает вам, сколько данных отправляется. Моя недавняя реализация проверила заголовки, чтобы узнать, сколько данных было отправлено, и когда он прочитал все, что я прекратил читать. –