Reputation: 43
The data in question is a PNG file prefixed by it's size as an int.
-Sending:
ns.Write(BitConverter.GetBytes((int)data.Length),0,4);
ns.Write(data, 0, data.Length);
-Reading:
byte[] sizearray = new byte[4];
ns.Read(sizearray, 0, 4);
int dataSize = BitConverter.ToInt32(sizearray,0);
byte[] data = new byte[dataSize];
ns.Read(data, 0, dataSize);
The recieved data is then saved to a file. I've also tried this with BeginRead/EndRead with the same result.
The issue is, while this works for most smaller images, it doesn't receive an image which is more then a few KB. The dataSize reads correctly, but after a few thousand bytes each time (~2900), the rest of the received data is 0. Example
Have I overlooked something, like a limit on how much can be sent at once?
Upvotes: 4
Views: 1491
Reputation: 160892
ns.Read(data, 0, dataSize);
Here's at least one of your problems: Read()
returns how many bytes were read, it's not guaranteed that dataSize
bytes were read.
This method reads data into the buffer parameter and returns the number of bytes successfully read. If no data is available for reading, the Read method returns 0. The Read operation reads as much data as is available, up to the number of bytes specified by the size parameter.
Upvotes: 1
Reputation: 1500525
You're ignoring the return value of Read
. Don't do that. Read
doesn't wait until it's read all of the data you requested. You should read in a loop until you've read everything you need to:
byte[] data = new byte[dataSize];
int index = 0;
while (index < dataSize)
{
int bytesRead = ns.Read(data, index, dataSize - index);
if (bytesRead <= 0)
{
// Or whatever exception you want
throw new InvalidDataException("Premature end of stream");
}
index += bytesRead;
}
In theory, you need to do the same even when reading dataSize
, although in practice I doubt whether you'll receive fewer than 4 bytes in one read.
You might want to use a BinaryReader
wrapped around the stream - then you could use ReadInt32
and ReadBytes
, where ReadBytes
will do the looping for you. (You'd still need to check the return value, but it would be simpler than doing it yourself.)
Upvotes: 5