Reputation: 77
I have a small problem, I am doing a video transmission between 2 PCs by TCP connection, what I do is take a screenshot of the screen, serialize it and send it to the other PC, the first time it works correctly, but the second time I get "ArgumentException " and the program no longer works, try to do it with BinaryFormatter it works but it is very slow.
both methods are called with an infinite while
public static void SerializeScreen(Stream stream, Bitmap Image)
{
BinaryWriter binaryWriter = new BinaryWriter(stream);
MemoryStream memory = new MemoryStream();
Image.Save(memory, System.Drawing.Imaging.ImageFormat.Jpeg);
binaryWriter.Write(memory.ToArray());
}
public static Image DeserializeScreen(Stream stream)
{
byte[] Buffer = new byte[500000];
BinaryReader binaryReader = new BinaryReader(stream);
int Bytes;
int LastPost = 0;
do
{
Bytes = binaryReader.Read(Buffer, LastPost, Buffer.Length - LastPost);
LastPost += Bytes;
} while (Bytes > 0);
MemoryStream memory = new MemoryStream(Buffer);
//Here is where I get the exception
return Image.FromStream(memory);
}
Upvotes: 0
Views: 63
Reputation: 595971
You are not delimiting your serialized images so that the deserializer knows where one image ends and the next begins. Especially since JPG is a variable-length format, depending on its compression level. Your deserializer is just blindly reading from the input stream until some arbitrary max byte count is reached, or the input stream runs out of bytes (ie, when the peer closes the TCP connection). That kind of logic will never work out.
I suggest you write out the serialized Image
's byte count to the destination stream before writing out the actual serialized bytes. That way, the deserializer can then read the count first, allocate that much memory, and read the bytes int it.
Try something more like this:
public static void SerializeScreen(Stream stream, Bitmap Image)
{
MemoryStream memory = new MemoryStream();
Image.Save(memory, System.Drawing.Imaging.ImageFormat.Jpeg);
int numBytes = (int) memory.Length;
BinaryWriter binaryWriter = new BinaryWriter(stream);
binaryWriter.Write(numBytes);
binaryWriter.Write(memory.GetBuffer(), 0, numBytes);
}
public static Image DeserializeScreen(Stream stream)
{
BinaryReader binaryReader = new BinaryReader(stream);
int numBytes = binaryReader.ReadInt32();
byte[] buffer = binaryReader.ReadBytes(numBytes);
MemoryStream memory = new MemoryStream(buffer);
return Image.FromStream(memory);
}
Upvotes: 2