=======================
=======================
=======================
출처: http://www.mkexdev.net/Article/Content.aspx?parentCategoryID=1&categoryID=21&ID=484
이번에는 소켓 통신 시 자주 사용되는 구조체를 주고 받는 것에 대해 질/답 형태의 글을 기록합니다
이전에 윈폼카페의 질문에 대한 답변입니다 (2008.01.03일 자료, http://cafe.naver.com/winform/49)
------------------------------------------------------------------------------------------------------------------------
질문>>>>>
제목도 뭐라고 써야할지 좀 난감 ㅋ
요즘 C#으로 네떡좀 만져볼라는데 상당히 거시기합니다.
C/C++에서 다음과 같은 내용이 있습니다.
typedef struct Data{
int a;
char b;
char str[30];
};
Data data;
...
char buffer[256];
memcpy(buffer, &data, sizeof(data));
이렇게 마지막에 memcpy를 해주면 구조체가 갖고있는 메모리를 그대로 복사해올 수 있죠.
혹은
void OnReceivePacket(char* packet){
Data* recvData = (Data*)packet;
}
이 처럼 형 변환을 통해 간단히 Data 구조체를 얻어낼 수도 있구요.
그런데 아직까지 제가 찾아본 결과로는...
C#에서는 하나씩 변환해서 넣어주어야 하는 듯 합니다.
public class Packet_CS_Hello {
public Packet_CS_Hello(byte[] from)
{
size = BitConverter.ToUInt16(from, 0);
id = BitConverter.ToUInt16(from, 2);
data = BitConverter.ToUInt32(from, 4);
}
public UInt32 data;
public ushort size;
public ushort id;
}
이 방법 말고 좀 더 깔끔한 (unsafe 말구 ^^) 방법은 없을까요?
답변 >>>>>
소켓 통신 시 구조체를 많이 주고 받기는 합니다
그 방법에 대한 질문 같은데요.....
샘플을 가지고 이야기 해 보겠습니다
다음과 같은 구조체를 정의 합니다
[Serializable] [StructLayout(LayoutKind.Sequential)] struct Data { [MarshalAs(UnmanagedType.U2, SizeConst = 2)] public ushort size; [MarshalAs(UnmanagedType.U2, SizeConst = 2)] public ushort id; [MarshalAs(UnmanagedType.U4, SizeConst = 4)] public UInt32 data; }; |
이 구조체를 바이트 배열로 변환 하여 네트워크 저 넘어로 전달하고 전달받은 곳에서는 다시 구조체로 변환하여
사용하고자 합니다
일단 동군님처럼
BitConvert를 이용해서 하나하나 끊어서 값을 찾아 낼 수 도 있습니다
ushort size = BitConverter.ToUInt16(bytesForWrite, 0); ushort id = BitConverter.ToUInt16(bytesForWrite, 2); UInt32 data = BitConverter.ToUInt32(bytesForWrite, 4); Data receiverData1; receiverData1.size = size; receiverData1.id = id; receiverData1.data = data;string result1 = String.Format("Size:{0},ID:{1},Data:{2}", receiverData1.size, receiverData1.id, receiverData1.data); Console.WriteLine(result1); |
물론 이 방법은 구조체 멤버들의 정확한 크기에 맞는 적절한 Converting 을 해 주어야 하는 불편함이 있습니다
또한 구조체 멤버의 종류가 다양하면 캐안습(?) 일 수 도 있습니다 ㅋㅋ
그 다음으로는
BinaryFormatter를 이용할 수 도 있습니다
NetworkStream 에 구조체를 Serialize 해서 수신측에서는 다시 Deserialize 하여 구조체를 얻는 방법입니다
즉, 마샬링을 이용하는 방법입니다
BinaryFormatter formatter = new BinaryFormatter(); Data receiverData = (Data) formatter.Deserialize(networkStream); |
물론
unsafe 를 이용한 방법도 가능합니다
Data receiveData; unsafe { fixed (byte* ptr = bytes) { receiveData= (Data )Marshal.PtrToStructure((IntPtr)ptr, typeof(Data )); } } return receiveData; 만일 Data가 구조체가 아니라 클래스라면 아래와 같이 해도 됩니다 Data receiveData; unsafe { fixed (byte* ptr = bytesForWrite) { Marshal.PtrToStructure((IntPtr)ptr, (Data)receiveData); } } |
여기서 제시된 샘플 프로젝트를 첨부 하였습니다. 다운로드 하여 실행 해 보신 후 참고하시길 바랍니다
그리고 마지막으로 덧붙이자면,닷넷 환경에서 소켓을 굳이 고집할 필요는 없습니다
리모팅이나 닷넷 3.0 의 WCF 와 같은 닷넷 환경에 진보된 형태의 분산어플리케이션 구축도 고려해 볼 만 합니다
그러면 이와 같은 문제(?) 상황은 덜 하리라 보입니다
그럼.. 즐 ~ 프 하삼요~~
=======================
=======================
=======================
출처: https://it-jerryfamily.tistory.com/entry/Program-C구조체를-이용한-소켓통신-마샬링-방법-콘솔화면?category=611730 [IT 이야기]
=======================
=======================
=======================
=======================
=======================
=======================
출처: https://it-jerryfamily.tistory.com/entry/Program-C구조체를-이용한-소켓통신1-마샬링-방법-콘솔-버전?category=611730 [IT 이야기]
=======================
=======================
=======================
[Program C#]구조체를 이용한 소켓통신1 - 마샬링 방법 - 윈도우 버전
출처: https://it-jerryfamily.tistory.com/entry/Program-C구조체를-이용한-소켓통신-마샬링-방법-윈도우화면 [IT 이야기]
=======================
=======================
=======================
출처: https://it-jerryfamily.tistory.com/entry/Program-C구조체를-이용한-소켓통신2-마샬링-방법-윈도우-버전?category=611730 [IT 이야기]
=======================
=======================
=======================
=======================
=======================
=======================
'프로그래밍 관련 > 언어들의 코딩들 C++ JAVA C# 등..' 카테고리의 다른 글
[C#] int, char, byte 등등의 배열 Array 복사,초기화 등등 관련 (0) | 2019.03.15 |
---|---|
[C#] 문자열 <-> 바이트(byte) 상호변환 그리고 문자열 인코딩(EncodingInfo.GetEncoding Method) 관련 (0) | 2019.03.14 |
[C#] C#의 클래스 혹은 구조체(class, struct)를 byte[]로 변환하는 방법 또는 반대로 (0) | 2019.03.13 |
[C#] Buffer.BlockCopy 으로 byte[] 데이터를 memmove, memcpy()처럼 이용 관련 (0) | 2019.03.13 |
[C#] Sizeof, Marshal.SizeOf Method 형 크기 SizeOf 관련 (0) | 2019.03.13 |
댓글 영역