2017-03-14 8 views
2

안녕하세요 저는 두 명의 플레이어가 서로 채팅하고 기본적으로 재생할 수있는 간단한 응용 프로그램을 작성합니다.특정 바이트에 쓰기 C#

내 앱은 수신 된 데이터 유형에 따라 다른 동작을 수행 할 수 있습니다.

예를 들어, 플레이어 1이 플레이어 2에게 메시지를 보내면 플레이어 2의 클라이언트의 응용 프로그램이 메시지 유형임을 인식하고 GUI를 업데이트하는 적절한 이벤트를 발생시킵니다.

한편, 플레이어 1이 이동하면 플레이어 2의 클라이언트 앱이 이동 유형임을 인식하고 적절한 이벤트를 수행합니다. (- MSG, 2 - MV 1) 바이트의 나머지 나머지 데이터

그래서 그것은

Byte[] buffer = new Byte[1024]; 

buffer[0] 데이터의 종류에 기록 할 수있는 데이터를위한 버퍼이다? 아니면이 기능을 구현하는 더 좋은 방법이 있습니까?

답변

5

BinaryReader/Writer를 사용할 수 있습니다. 예를 들어

:

보낸 사람 :

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

사용 stream.Position는 기록 된 데이터의 길이를 결정합니다.


수신기 :

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

'기록이있는 경우, 예를 들어, "이동 유형"에 대한 데이터를 포함하는 구조체 당신이 뭔가를 할 수 (문자열)은 다른 비 - .NET 시스템과의 "비 - 높은"상호 운용성을 가지고 있습니다 (문자열을 특정 방식으로 포맷하기 때문에 문자열을 7 비트 길이로 늘리기 때문에), BinaryWriter의 기본 인코딩 UTF8입니다 (문제가 아니며 단지 정보 임). 다른'Write (something)'은 모두 매우 간단하므로 매우 상호 운용성이 좋습니다. (10 진수는'decimal'은 .NET이기 때문에 매우 낮은 상호 운용성을가집니다.) – xanatos

2

어떻게 그 데이터를 마샬링에 대한?

보낸 사람 :

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

수신기 : 작은 메모로

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

구조체 사용의 단점 이다; 고정 길이, 문자열 및 구조체 s..ks, 첫 번째 int를 packettype으로 정의해야합니다. 그러나 .. 그것은 효과가 있습니다. –

+0

이것은 사실이지만, "이동"또는 "메시지"로 계속 진행하는 경우 코드가 더 mantainable하고 덜 지저분 해집니다. – ArenaLor

+0

나는 그것에 동의하지 않는다. 직렬화에 struct를 사용하는 것은 너무 엄격합니다. 문제는 목록 등으로 객체를 직렬화하고자 할 때 발생합니다. 객체에서 binaryreaders/writers의 사용을 자동화하는 여러 가지 방법이 있습니다. 예를 들어, serialize/deserialize 메소드를 강제 실행하는 인터페이스. 나는 심지어 구조체 대신에'BinarySerializer'를 선호한다. 서버 및 클라이언트가 .NET 일 때만 계산됩니다. 내가 말했듯이 구조체를 사용하는 것은 나쁘지는 않지만 단지 제 의견입니다. –

관련 문제