J'ai un code réseau pour traiter une connexion TCP arbitraire..NET NetworkStream Lecture lenteur
Tout semble fonctionner comme prévu mais semble lent. Quand j'ai profilé le code, il semble passer 600 ms dans NetworkStream.Read() et je me demande comment l'améliorer. J'ai manipulé les tailles des tampons et alterné entre un tampon massif pour lire toutes les données en une fois ou un petit qui devrait concaténer les données dans un StringBuilder. Actuellement, le client que j'utilise est un navigateur Web, mais ce code est générique et il se peut qu'il ne s'agisse pas de données HTTP qui lui sont envoyées. Des idées?
Mon code est le suivant:
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: je reçois à peu près les mêmes chiffres sur deux machines entièrement séparées (ma machine de développement XP et 2003 une boîte dans une colo). J'ai mis un peu de temps dans le code autour des parties concernées (en utilisant System.Diagnostic.StopWatch) et de vidage à un journal:
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
J'ai le même problème. Je vois votre solution dans ce post, mais que diriez-vous de la nReadTimeOutMS, et bTurboMode. Pourriez-vous me donner une description complète?Je suis très intéressé et apprécié si vous partagez avec moi ce cours. Merci d'avance. – olidev
Mon implémentation était très basique, j'en ai ré-écrit un gros morceau après ce post pour le faire correctement. Le point crucial est que vous ne comptez que sur les délais, etc., si le client expéditeur ne vous dit pas combien de données sont envoyées. Ma mise en œuvre récente a vérifié les en-têtes pour voir combien de données étaient envoyées et quand il avait lu tout ce que j'avais arrêté de lire. –