I am sending a filename(string), filesize(int), and the file(byte[]). What is happening is that in certain cases, depending on how quickly the data gets processed on the server side, the NetworkStream has read the data that I dont need yet.
Example: I do a .Read to get the filename, I will get the data for filename,filesize and the files raw data. I assume this happens because the server just does a .Write and writes the data to the stream when the first .Read hasnt executed yet. This ends up clobbering my filesize .Read. Now when I do a .Read for my filesize I am showing a HUGE number and when I go to read for the file itself and allocation a new byte[] based on the read files size i get an OutOfMemory exception.
How do I synchronize the Read properly? The examples I am finding on the net do it the way I do.
Some code:
private void ReadandSaveFileFromServer(TcpClient clientATF, NetworkStream currentStream, string locationToSave)
{
int fileSize = 0;
string fileName = "";
int readPos = 0;
int bytesRead = -1;
fileName = ReadStringFromServer(clientATF, currentStream);
fileSize = ReadIntFromServer(clientATF, currentStream);
byte[] fileSent = new byte[fileSize];
while (bytesRead != 0)
{
if (currentStream.CanRead && clientATF.Connected)
{
bytesRead = currentStream.Read(fileSent, readPos, fileSent.Length);
readPos += bytesRead;
if (readPos == bytesRead)
{
break;
}
}
else
{
WriteToConsole("Log Transfer Failed");
break;
}
}
WriteToConsole("Log Recieved");
File.WriteAllBytes(locationToSave + "\\" + fileName, fileSent);
}
private string ReadStringFromServer(TcpClient clientATF, NetworkStream currentStream)
{
int i = -1;
string builtString = "";
byte[] stringFromClient = new byte[256];
if (clientATF.Connected && currentStream.CanRead)
{
i = currentStream.Read(stringFromClient, 0, stringFromClient.Length);
builtString = System.Text.Encoding.ASCII.GetString(stringFromClient, 0, i);
}
else
{
return "Connection Error";
}
return builtString;
}
private int ReadIntFromServer(TcpClient clientATF, NetworkStream currentStream)
{
int i = -1 ;
int builtInteger = 0;
byte[] integerFromClient = new byte[256];
int offset = 0;
if (clientATF.Connected && currentStream.CanRead)
{
i = currentStream.Read(integerFromClient, offset, integerFromClient.Length);
builtInteger = BitConverter.ToInt32(integerFromClient, 0);
}
else
{
return -1;
}
return builtInteger;
}
I have tried using a offset...with no luch. Your help is appreciated.
I started another question but it relates to something else.
Thanks in advance Sean
EDIT: Here is my send string code:
private void SendToClient( TcpClient clientATF, NetworkStream currentStream, string messageToSend)
{
byte[] messageAsByteArray = new byte[256];
messageAsByteArray = Encoding.ASCII.GetBytes(messageToSend);
if (clientATF.Connected && currentStream.CanWrite)
{
//send the string to the client
currentStream.Write(messageAsByteArray, 0, messageAsByteArray.Length);
}
}