I am sending my own struct "packet" object through the TCP interface that C# offers with TCPListener and TCPClient.
This is my struct
[Serializable]
struct RemuseNetworkPacket
{
public String ApplicationCode;
public String ReceiverCode;
public RemusePacketType Type;
public uint ID;
public uint cID;
public String Name;
public byte[] Data;
public String Text;
public System.Drawing.Point Coords;
public String Timestamp;
public String Time;
public String SenderName;
public byte[] Serialize()
{
var buffer = new byte[Marshal.SizeOf(typeof(RemuseNetworkPacket))];
var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
var pBuffer = gch.AddrOfPinnedObject();
Marshal.StructureToPtr(this, pBuffer, false);
gch.Free();
return buffer;
}
public void Deserialize(byte[] data)
{
var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
this = (RemuseNetworkPacket)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(RemuseNetworkPacket));
gch.Free();
}
}
I am using the serialization methods within the struct to prepare and retrieve the data before and after sending.
In order to to let the receiver know the incoming data's size, I add some header data to the bytes being sent, in the format of l=212;... which means length = 212; and the ... is the rest of the packet.
On the receiving end I search for this until I find the entire l=xxxx; then I make a new byte array without the header, then attempt to deserialize the data.
The packet byte to use for deserialization is: tcp stream's buffer.Length - foundHeaderSize (l=xxxx;)
If I run the client and server on the same machine, it works without errors, however if I have the client and server on separate machines, I get exceptions and it crashes.
The exception takes place when the packet is being deserialized, saying:
*System.Runtime.InteropServices.SafeArrayTypeMismatchException
Mismatch has occurred between the runtime type of the array and the sb type recorded in the metadata at
System.Runtime.InteropServices.PtrToStructureHelper
Stacktrace:
System.Runtime.InteropServices.PtrToStructureHelper
(IntPtr ptr, Object structure, Boolean allowValueClasses) at
System.Runtime.InteropServices.PtrToStructure(IntPtr ptr, Type structureType..*
I'm asking for help to identify the cause of the problem.
Can I not do it like this with objects that came over the network?
Question&Answers:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…