J'ai un problème avec les données de lecture NetworkStream du tampon de socket qui ne devraient pas s'y trouver. J'envoie d'énormes tampons au passage. En ce moment je viens de tester sur le localhost.NetworkStream lit les données qui ne devraient pas s'y trouver
Voici comment je lis les données, les 4 premiers octets contiennent la longueur du message, puis je viens de lire en 4096 morceaux jusqu'à ce qu'il atteigne la longueur du message.
protected TcpClient tcpObject;
protected NetworkStream tcpStream;
private void HandleComm()
{
try
{
tcpStream = tcpObject.GetStream();
byte[] totalByteAray = new byte[constIntSize];
byte[] message = new byte[constChunkSize];
byte[] fullMessage = new byte[0];
//this is how many bytes long the message will be
int totalBytes = 0;
int currentBytes = 0;
int chunkSize = constChunkSize;
while (true)
{
//skip reading if no data is available
//DataAvailable does not tell you when all the data has arrived
//it just tell you if some data has arrived
if (tcpStream.CanRead)
{
totalBytes = 0;
currentBytes = 0;
message = new byte[constChunkSize];
chunkSize = constChunkSize;
//The first 4 bytes of the message will always contain the length of the message, not including
//the first 4 bytes. This is how you know when to stop reading.
tcpStream.Read(totalByteAray, 0, constIntSize);
//there are 4 bytes in a 32 bit number, so totalByteArrayContains 4 index that is a byte which is
//the 32 bit int that tells us how many bytes the whole message will be.
//now convert the totalByteArray to a 32bit int
totalBytes = BitConverter.ToInt32(totalByteAray, 0);
Console.WriteLine("reading " + totalBytes);
//fullMessage will contain the entire message but it has to be built message by message.
fullMessage = new byte[totalBytes];
//keep reading until we get all the data
while (currentBytes < totalBytes)
{
//when you send something over TCP it will some times get split up
//this is why you only read in chuncks, 4096 is a safe amount of bytes
//to split the data into.
if (totalBytes - currentBytes < constChunkSize)
{
chunkSize = totalBytes - currentBytes;
message = new byte[chunkSize];
}
tcpStream.Read(message, 0, chunkSize);
//since we know each chunk will always come in at 4096 bytes if it doesn't that means that it's the end
//this part cuts off the extra empty bytes
//copy the message to fullMessage starting at current bytes and ending with the bytes left
message.CopyTo(fullMessage, currentBytes);
currentBytes += chunkSize;
}
//message has successfully been received
if (totalBytes != 0)
{
if (OnRawDataReceived != null)
{
RawDataReceivedArgs args = new RawDataReceivedArgs();
args.Data = new byte[fullMessage.Length];
fullMessage.CopyTo(args.Data, 0);
OnRawDataReceived(this, args);
}
totalBytes = 0;
}
}
}
}
catch
{
connectionStatus = ConnectionStatus.NotConnected;
if (OnDisConnect != null)
OnDisConnect(this, null);
}
}
Voici comment j'envoie les données, je viens d'obtenir la longueur du message, puis créer un nouveau message avec les 4 premiers octets étant la longueur du message et le reste étant le message réel.
protected void sendData(byte[] data)
{
//we need to know how big the data that we are sending will be
int length = data.Length;
System.Console.WriteLine("writing " + length);
//convert the 32bit int to a 4 byte array
byte[] lengthArray = BitConverter.GetBytes(length);
//init the main byte array that will be sent over
byte[] buffer = new byte[length + constIntSize];
//the first 4 bytes will contain the length of the data
lengthArray.CopyTo(buffer, 0);
//the rest of the buffer will contain the data being sent
data.CopyTo(buffer, constIntSize);
//wite it to the client stream
tcpStream.Write(buffer, 0, length + constIntSize);
//now send it
tcpStream.Flush();
}
Pour une raison quelconque, je reçois des données de lecture qui ne doivent pas figurer dans le tampon. Voici la sortie de la console.
serveur------------- client
écriture 1024 -> Lecture 1024
lecture 1.228.800 < - écriture 1228800
écriture 1024 -> 1024 lecture
lecture 1.228.800 < - écriture 1228800
lecture 7.224.842
Donc, quand je clique sur un bouton, il envoie une requête disant que je veux une image d'une caméra Web, la demande est de 1024 octets. Le client le lit et envoie l'image qui est le 1228800 octets. La première fois que je fais cela, ça fonctionne toujours. La deuxième fois que je l'ai cliqué, le client a renvoyé les 1228800 octets, le serveur a lu le bon nombre d'octets et a trouvé plus d'octets à lire lorsque le tampon de socket aurait dû être vide. Je n'avais pas 7224842 octets dans le tampon socket, c'est exactement ce que disent les 4 premiers octets de la lecture.
Des idées sur les raisons pour lesquelles le tampon reçoit des données supplémentaires? Tout semble bien fonctionner quand j'envoie des messages plus petits, mais cela me rend fou.
La méthode Read retourne NetworkStream 'Le nombre d'octets lus à partir du NetworkStream.'. Vous ignorez la valeur de retour. Vous ne pouvez pas supposer que la valeur va être la taille du tampon. –