Question

Lors de la lecture de données sur le réseau, vous spécifiez un tampon dans lequel recevoir les données:

byte[] b = new byte[4096];
socket.Receive(b);

Maintenant, ma première idée est bien sûr de réutiliser le tampon de réception en le déclarant comme une variable membre de la classe. Mon problème suivant est que je n'ai pas reçu toutes les données que j'attendais, je dois donc mettre mes données en mémoire tampon. Ceci est facile à réaliser en gardant une trace du nombre d'octets reçus et en spécifiant le décalage:

socket.Receive(m_ReceiveBuffer, count, m_ReceiveBuffer.Length - count);

Maintenant, le problème ici est que si cela ne suffit toujours pas, je suppose que je dois agrandir le tampon, ce qui signifie copier la mémoire, et continuer à recevoir dans ce tampon. En supposant que quelque chose se passe mal, cette mémoire tampon continuera de croître et, si les messages reçus sont suffisamment volumineux, le système manque de mémoire.

Avez-vous des idées pour gérer cela correctement? Existe-t-il un meilleur moyen de recevoir les données que de simplement remplir, copier, grandir, remplir, copier, grandir?

Était-ce utile?

La solution

lu en morceaux:

const int ChunkSize = 4096;
int bytesRead;
byte[] buffer = new byte[ChunkSize];
while ((bytesRead = socket.Receive(buffer, 0, ChunkSize, SocketFlags.None)) > 0)
{
    byte[] actualBytesRead = new byte[bytesRead];
    Buffer.BlockCopy(buffer, 0, actualBytesRead, 0, bytesRead);
    // Do something with actualBytesRead, 
    // maybe add it to a list or write it to a stream somewhere
}

Autres conseils

Avant de commencer avec SYstem.Net.Sockets.Socket, êtes-vous sûr que vous ne pouvez pas utiliser System.Net.Sockets.TcpClient (ou UdpClient) pour que tout le tampon désordonné fonctionne pour vous et le transforme en un système facilement gérable? flux?

Si ce n'est pas le cas, rappelez-vous que la quantité de données que vous recevez ne doit pas forcément être égale à celle que vous demandez, vous devez donc toujours regarder la valeur de retour de la fonction recieve. Et le seul moyen de ne pas manquer de mémoire est de traiter réellement ce que vous recevez.

Commencez par séparer le code pour recevoir les données et les traiter. Le tampon de réception ne doit conserver les données que jusqu'à ce que le code ait la possibilité de les copier dans la zone de traitement. La zone de traitement est l'endroit où vous déterminerez si vous avez reçu suffisamment de données pour faire quelque chose d'utile. Ne laissez pas les données dans le tampon de réception du réseau jusqu'à ce que cela se produise. Pour le tampon de réception réseau, je pense qu’utiliser un tampon circulaire vous aidera avec votre idée de réutiliser un tampon. J'espère que vous avez une idée de la taille des messages. Cela aidera à déterminer la taille de la mémoire tampon. Si vous affirmez (ou quelque chose de similaire) que les pointeurs de lecture et d'écriture du tampon circulaire se rencontrent, augmentez la taille du tampon. Une fois que la taille du tampon est suffisante, vous devriez être capable de lire suffisamment de données du tampon dans le code de traitement à une vitesse suffisamment rapide pour que le tampon circulaire ne déborde pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top