问题
I'm creating a C# application (Client & Server). They're seperate projects and both reference a DLL that can serialize and deserialize any object that is inputed into them.
Everything is working fine, until I start working with live desktop monitoring (Video-ish). The DLL contains a custom "Screenshot" class that takes in a bitmap & writes it to the public memorystream for that class. Here is how it is all done:
- Client button takes screenshot of whole screen (as a bitmap)
- Client constructs a Screenshot object, serializes it, and sends it off to the server. (Serializing it turns it into bytes) Client then repeats these steps to constantly send screenshots
- Server receives these bytes, deserializes it, checks if it's a Screenshot type, then raises an event & displays this image on the form if true.
Yes I do receive a live image feed and it's displayed on the form, but this only works for like 3 to 10 seconds. I'm getting 3 exceptions in all, they occur randomly from the clients.
I'll post the screenshots with some details about them too, excuse the weird exception handler box. https://imgur.com/a/Uv4r6wY
Here is the Serialize and Deserialize code inside the DLL:
public static byte[] Serialize(Object paramObj)
{
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, paramObj);
return ms.ToArray();
}
}
public static Object Deserialize(byte[] paramBuffer)
{
using (MemoryStream ms = new MemoryStream(paramBuffer))
{
BinaryFormatter bf = new BinaryFormatter();
//ms.Position = 0;
ms.Seek(0, SeekOrigin.Begin);
return (Object)bf.Deserialize(ms);
}
}
I've been spending hours researching these errors and come up with nothing, anything that I seem to apply creates another error.
Thank you for taking your time to analyze my messy code. Really ty.
If you're curious on how the server handles the received data:
public void receiveAll()
{
byte[] _buffer = new byte[55000];
_clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), _clientSocket);
void ReceiveCallback(IAsyncResult AR)
{
try
{
_clientSocket = (Socket)AR.AsyncState;
int received = _clientSocket.EndReceive(AR);
byte[] receivedbuffer = new byte[received];
Array.Copy(_buffer, receivedbuffer, received);
// The "ObjectHandler" is the class to Ser & Deser in the DLL
Object data = ObjectHandler.Deserialize(receivedbuffer);
try
{
// Check the data that is received & determine type
}
catch (Exception ex)
{
// Show Exception box
}
// Repeat the receive process...
_clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), _clientSocket);
}
catch (Exception ex)
{
RemoveClient();
// Show Exception box
}
}
}
回答1:
The serialization exceptions simply mean that the data is somehow incomplete or damaged. The issue lies with your data transmission, not your serialization.
I'm assuming you're using a TCP socket for the connection? There is no guarantee that a read call on a Socket
(or TcpClient
, Stream
etc.) gives you all the data you expect at once. The buffer is filled with up to size
number of bytes, from the data that is currently available on the receiving side. Especially when sending large amounts of data over a network, it is likely to arrive in multiple partial packets rather than all at the same time. Also, a single receive call may return both the end of the current message and the beginning of the next.
You need to repeatedly call BeginReceive
in a loop until you know you have the complete message, e.g. by manually prefixing the transmitted data with a length value on the sending side and then waiting until you have buffered at least that amount of data on the receiving side.
来源:https://stackoverflow.com/questions/54972898/c-sharp-binary-formatter-serialization-deserialization-3-random-exceptions