尝试将通过套接字接收的byte []数组转换为结构

时间:2016-08-04 20:56:39

标签: c# marshalling

使用TcpListener,我从客户端收到一个字节数组,并立即尝试从中创建一个stuct(通过Marshal.PtrToStructure)

这是我到目前为止所做的:

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();
    }
}           

运行这个让我:

  

“类型'System.AccessViolationException'的未处理异常   发生在mscorlib.dll

附加信息:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。“

任何建议都非常受欢迎,我是C#的新手。

编辑:我忘了包含Record结构:

    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;

    }

1 个答案:

答案 0 :(得分:1)

你在这里做了一个基本的假设 - 你可以简单地从网上获取一些东西并对结构进行一次字节爆炸(这可能是也可能不是你的直接问题)。

更好的方法是使用BinaryReader从字段中读取它(如果您拥有发件人,则使用BinaryWriter写入它)。 BinaryReader可以直接在网络流的顶部实例化,它可以很好地等待接收正确的字节数等。

var br = new BinaryReader(netStream);
var rec = new Record();
rec.Station = br.ReadString();
rec.EvtActive = br.ReadInt32();
.....