Reputation: 499
Using TcpListener, I receive a byte array from a client and immediate try to create a stuct out of it (via Marshal.PtrToStructure)
This is what I have so far:
public static void ClientListener(object obj)
{
TcpClient client = (TcpClient)obj;
NetworkStream netStream = client.GetStream();
MemoryStream memStream = new MemoryStream();
byte[] bytes = new byte[client.ReceiveBufferSize];
int bytesRead;
while((bytesRead = netStream.Read(bytes, 0, bytes.Length)) > 0)
{
memStream.Write(bytes, 0, bytesRead);
}
byte[] result = memStream.ToArray();
Record test = new Record();
test = ByteToStruct<Record>(result);
Console.WriteLine(test.Station);
netStream.Close();
memStream.Close();
client.Close();
Console.WriteLine("Closed");
//Record test1 = new Record("a", "b", 1, 200, "e", "f", "g", 2, 3, "j", "k");
}
public static Record ByteToStruct<Record>(byte[] data)
{
GCHandle gch = GCHandle.Alloc(data, GCHandleType.Pinned);
try
{
return (Record)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(Record));
}
finally
{
gch.Free();
}
}
Running this get me:
"An unhandled exception of type 'System.AccessViolationException' occurred in mscorlib.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Any advice is wildly appreciated, I'm new to C#.
EDIT: I forgot to include the Record struct:
public Record(string a, string b, int c, string d, string e, string f, string g, int h, int i, string j, string k)
{
Console.WriteLine("inside struct 0");
Station = a;
UserName = b;
EvtActive = c;
EvtTime = d;
EvtTimeString = e;
LocCode = f;
LastLoop = g;
CompLvl = h;
RecordID = i;
ConnectTime = j;
Notes = k;
}
Upvotes: 0
Views: 344
Reputation: 50110
you are making a fundamental assumption here - that you can simply getsomething off the wire and do a byte blast into a struct (this may or may not be what your immediate problem is).
Much better is to read it off the wire field by field using BinaryReader (adn write it using BinaryWriter if you own the sender). BinaryReader can be instantiate directly on top of the network stream, it will do all the nice waiting for the correct number of bytes to be received etc.
ie.
var br = new BinaryReader(netStream);
var rec = new Record();
rec.Station = br.ReadString();
rec.EvtActive = br.ReadInt32();
.....
Upvotes: 1