2017-03-14 2 views
2

Hey ich schreibe einfache Anwendung, die zwei Spieler miteinander reden und grundsätzlich spielen können.Schreiben in ein bestimmtes Byte C#

Meine App kann je nach empfangenem Datentyp verschiedene Aktionen ausführen.

Zum Beispiel, wenn Spieler 1 eine Nachricht an Spieler 2 sendet, erkennt die Anwendung auf dem Client von Spieler 2, dass es sich um einen Nachrichtentyp handelt, und feuert ein geeignetes Ereignis, das die GUI aktualisiert.

Auf der anderen Seite, wenn Spieler 1 einen Zug macht, erkennt die Client-App von Spieler 2, dass es sich um einen Bewegungstyp handelt und geeignete Ereignisse durchführt.

So ist es Puffer für Daten

Byte[] buffer = new Byte[1024]; 

Ist es möglich, auf buffer[0] Art von Daten zu schreiben (1 - MSG, 2 - MV) und der übrigen Daten restlichen Bytes? Oder gibt es vielleicht den besseren Weg, diese Funktionalität umzusetzen?

Antwort

5

Sie könnten den BinaryReader/Writer dafür verwenden.

Zum Beispiel:

Sender:

Byte[] buffer = new Byte[1024]; 

MemoryStream stream = new MemoryStream(buffer); 
BinaryWriter writer = new BinaryWriter(stream); 

writer.Write(1); // message type. (command) 
writer.Write("Hi there"); 
writer.Write(3.1415); 

Verwenden der stream.Position die Länge der zu schreibenden Daten zu bestimmen.


Empfänger:

Byte[] buffer = new Byte[1024]; 

MemoryStream stream = new MemoryStream(buffer); 
BinaryReader reader = new BinaryReader(stream); 

int command = reader.ReadInt32(); 

switch(command) 
{ 
    case 1: // chat message 
     string message = reader.ReadString(); 
     double whateverValue = reader.ReadDouble(); 
     break; 

    case 2: // etc. 
     break; 
} 
+0

Als kleine Anmerkung, 'schreiben (Zeichenkette) "hat" nicht-hohe "Interoperabilität mit anderen Nicht-.NET-Systemen (weil es die Zeichenketten in einer bestimmten Weise formatiert, wobei die Zeichenkette mit einer 7-Bit-codierten Länge vorangestellt wird) PLUS die Standardcodierung von' BinaryWriter' ist UTF8 (das ist kein Problem, ist nur eine Information). Die anderen 'Write (something)' sind alle sehr einfach, daher haben sie eine sehr hohe Interoperabilität (ok ... 'Write (decimal)' hat eine sehr geringe Interoperabilität, da 'decimal' nur .NET ist) – xanatos

2

Was ist mit den Daten Marshalling? Wenn Sie zum Beispiel eine Struktur für "Bewegungstyp" Daten enthalten, könnten Sie so etwas wie tun:

Sender:

SOME_STRUCT data = new SOME_STRUCT(); 
int structSize = Marshal.SizeOf(data); 
// you fill your struct here 
var msgBytes = new Byte[1024]; 

IntPtr pointer = Marshal.AllocHGlobal(structSize); 
Marshal.StructureToPtr(data, pointer, true); 
Marshal.Copy(pointer, msgBytes, 0, size); 
Marshal.FreeHGlobal(pointer); 

Empfänger:

SOME_STRUCT receivedData = new SOME_STRUCT(); 
int structSize = Marshal.SizeOf(data); 
// You receive your data here 
var receivedBytes = msgBytes; 

GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); 
IntPtr pointer = handle.AddrOfPinnedObject(); 
Marshal.Copy(receivedBytes, 0, pointer, (int)structSize); 
+0

Der Nachteil der Verwendung von Strukturen ist; feste Länge, Zeichenfolgen und Strukturen s..ks, Sie müssen das erste int als Pakettyp definieren. Aber .. es wird funktionieren. –

+0

Das ist richtig, aber sie machen Code aufrechterhaltbar und weniger unordentlich, wenn Sie viel mit einer "Bewegung" oder einer "Nachricht" machen. – ArenaLor

+0

Dem stimme ich nicht zu. Die Verwendung von Structs für die Serialisierung ist viel zu starr. Das Problem tritt auf, wenn Sie Objekte mit Listen usw. serialisieren möchten. Es gibt viele Möglichkeiten, die Verwendung von Binaryreaders/Writern in Objekten zu automatisieren. Zum Beispiel eine Schnittstelle, die Methoden zum Serialisieren/Deserialisieren erzwingt. Ich bevorzuge sogar den 'BinarySerializer' anstelle von Strukturen. Dies gilt nur, wenn der Server und der Client .NET sind. Wie ich bereits sagte, ist die Verwendung einer Struktur nicht schlecht, aber es ist nur meine Meinung. –