2016-08-04 32 views
0

Mit TcpListener empfangen wurden, erhalte ich ein Byte-Array von einem Client und sofort versuchen, eine stuct aus ihn heraus (über Marshal.PtrToStructure)Des Versuch, ein byte [] Array zu konvertieren, die über eine Steckdose in ein struct

zu erstellen

Das ist, was ich habe, so weit:

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

das mich zum Laufen bringen:

„Eine nicht behandelte Ausnahme des Typs 'System.AccessViolationException' ist in mscorlib.dll aufgetreten

Zusätzliche Informationen: Es wurde versucht, geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist „

Jede Beratung wild geschätzt wird, ich C# bin neu

EDIT:.. Ich habe vergessen, die Record-Struktur enthalten:

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; 

    } 
+0

Scheint wie Ihre komplizierenden Dinge da. Ich nehme an, Record ist deine Struktur? Hat es eine Byte-Array-Eigenschaft? Wenn nicht, was dein Tun nicht funktioniert. Sie müssen ihm eine Eigenschaft geben, die ein Byte [] ist, um das zu tun, Sie können eine Struktur nicht einfach dazu bringen, einen anderen Typ darin zu haben. Im Allgemeinen werden Strukturen in C# missverstanden/verwendet und es ist besser, nur eine Klasse zu verwenden. – kmcc049

+0

Was würde ich machen, nachdem ich ihm eine byte [] Eigenschaft gegeben habe? Willst du damit sagen, dass alle Variablen im Konstruktor byte [] s sind? – MrDysprosium

Antwort

1

Sie machen hier eine grundlegende Annahme - dass Sie einfach etwas von der Leitung bekommen können und ein Byte in eine Struktur streuen (das kann oder kann nicht das sein, was Ihr unmittelbares Problem ist).

Viel besser ist es, es zu lesen Draht für Feld mit BinaryReader (ADN schreiben Verwenden Sie BinaryWriter, wenn Sie den Absender besitzen). BinaryReader kann direkt am Anfang des Netzwerk-Streams instanziiert werden, es wird alles auf die richtige Anzahl von Bytes warten, die empfangen werden usw.

ie.

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

Sie sagen "Feld für Feld", aber was bedeutet das? Wenn ich die Daten erhalte (ich besitze nicht den Absender), kommt es in einem riesigen Block von 1324 Bytes. – MrDysprosium

+0

siehe bearbeitet Kern – pm100

+0

Jetzt ist das interessant. Also, wenn dieser Client (den ich nicht besitze) schickt mir einen großen Ole-Dump von etwa 1324 Bytes Daten, aber es ist immer in der Reihenfolge, die ich in meiner Record-Struktur eingerichtet habe, wird BinaryReader den "ersten" String nehmen und wenden Sie es auf Station an, nehmen Sie dann den "zweiten" String und wenden Sie ihn auf Username, etc ... an oder muss ich BinaryReader mitteilen, wie meine Bytes für jede Variable reserviert sind? Vielen Dank für Ihre Hilfe btw, ich schätze es wirklich. – MrDysprosium