임의의 TCP 연결을 처리 할 수있는 네트워크 코드가 있습니다..NET NetworkStream 느린 읽기
모두 예상대로 작동하지만 느리게 보입니다. 내가 코드를 프로파일 링했을 때 NetworkStream.Read()에서 600ms를 소비하는 것처럼 보였고이를 개선하는 방법이 궁금합니다. 나는 버퍼 크기를 집중적으로 다루었 다. 한 번에 모든 데이터를 읽거나 데이터를 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
내 구현은 매우 기본적인 것이므로이 게시물 이후에 제대로 수행하기 위해 큰 덩어리를 다시 작성했습니다. 문제의 요지는 전송 클라이언트가 전송되는 데이터의 양을 알려주지 않으면 시간 초과 등에만 의존한다는 것입니다. 최근 구현에서는 헤더를 검사하여 전송되는 데이터의 양과 읽은 모든 것을 읽은 시간을 확인했습니다. –