통신을 할때... 패킷의 규격을 정하고
이 규격에 맞게 구조체를 만든다음,
소켓으로 구조체를 던지고 받는다면 참 편리할 것이다.
다만... 비주얼베이직의 경우에는 이 구조체라는 Object 를 바로 던지고 받고 할 수 없다는 문제가 있다.
VB6 의 경우라면 API함수를 통해 구조체의 메모리포인터를 가지고 바이트배열 변수에 복사해버리는 방법이 있었지만,
VB .NET 의 경우에는 구조체 변수의 메모리포인터를 읽을 도리가 없으니...
하지만... 프레임워크의 도움을 받으면 손쉽게 가능하단다...
그래서... 찌질한 소스를 짜 보았다...
제작까지 30분... 후덜덜...모듈을 하나 만들고... 그 안에 코딩한다...
Imports System.Runtime.InteropServices ' Marshal 함수가 들어있는 프레임워크 구성원
Module Module1
' 패킷 구조체
<StructLayout(LayoutKind.Sequential)> _
Public Structure Packet
Dim SOH As Byte ' Start of Header : 0x01. Header의 진입점 선언.
Dim pNo As Uint32 ' 패킷의 순번. 4,294,967,295번 초과시 0으로 카운트리셋.
Dim pSize As UInt16 ' 실 데이터(Bydy부분)의 데이터 길이. 단위는 Bytes.
Dim pEnc As Byte ' 데이터의 암호화종류 : 0x00-None 0x01-XOR 0x02-BlowFish 0x03-Base64
Dim pType As UInt16 ' 패킷타입. 시스템메시지, 채팅메시지... 등등...
Dim SOT As Byte ' Start of Text. 0x02. Body의 진입점 선언.
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=65500)> _
Dim Body() As Byte ' 실제로 처리할 데이터 부분.
Dim EXT As Byte ' End of Text. 0x03. 데이터의 종단점 선언.
Dim EOT As Byte ' End of Trance. 0x04. 전송의 종단점 선언.
End Structure
Public Sub Bytes2Structure(ByVal b As Byte(), ByRef s As Object)
Dim StructureType As Type = GetType(Packet)
Dim ibyteIndex As Integer = 0
Dim iStructSize As Integer = Marshal.SizeOf(StructureType)
Dim buffer As IntPtr
If (iStructSize > b.Length) Then
Exit Sub
Else
Buffer = Marshal.AllocHGlobal(iStructSize)
Marshal.Copy(b, ibyteIndex, buffer, iStructSize)
s = Marshal.PtrToStructure(buffer, StructureType)
Marshal.FreeHGlobal(buffer)
End If
End Sub
Public Sub Structure2Bytes(ByVal s As Object, ByRef b As Byte())
Dim iStructSize As Integer = Marshal.SizeOf(s)
Dim buffer As IntPtr = Marshal.AllocHGlobal(iStructSize)
ReDim b(iStructSize - 1)
Marshal.StructureToPtr(s, buffer, False)
Marshal.Copy(buffer, b, 0, iStructSize)
Marshal.FreeHGlobal(buffer)
End Sub
End Module
사용법은 다음과 같다...
// 구조체를 바이트배열에 담을때...
Structure2Bytes([구조체], &ref[바이트배열])
// 바이트배열을 구조체에 담을때...
Bytes2Structure([바이트배열], &ref[구조체])
- 2009/11/08 12:53
- aurelie.egloos.com/2741893
- 덧글수 : 3
덧글
-
안녕하세요...
윌 2009/11/09 12:45 # 삭제 답글
소스 잘 보았습니다...
저도 최근에 .net을 하면서 구조체 전송하는 부분에서
쉽잖은 어려움을 격는데요...
한프로그램내에서 struct2byte -> byte2struct 하면 정상적으로...잘 됩니다...
그런데
C/S 상에서..
struct2byte -> socket.send -> socket.recv -> byte2struct 하면..
구조체가 제대로 변환이 안되네요.. 숫자만 변환되고..;;
실제적으로 send시와 recv 시 전송되는 데이타는 동일 한데 말이죠..
답답한 나머지 이렇게 글을 남깁니다...
이런 경우는 없으셧는지요..??
감사합니ㅏㄷ...TT -
음... 제 경우에는 잘 되서 잘 모르겠네요... ' ㅅ';
아우렐리에 2009/11/10 20:03 #
VS 버전이 어찌되실지 모르겠지만... 저는 VS2008EE 이구요... 음;
(버전이 달라도 이 코드는 별다른 변이사항이 없는걸로 알고있지만...)
디버깅 모드에서 에러메시지를 참고하시면서 수정하면 손쉽게 될 것 같아요...
(.net 와서 디버깅지원이 확실히 좋아진 느낌이니... :D) -
저랑... VS버젼도 같은거 같은데...
윌 2009/11/11 03:00 # 삭제 답글
이상하네요...
혹시 약간 짬이 되신다면.. 소스좀 한번 봐주실수 있으세요??
지금 이것때문에 1주일때 해메고 있네요..;;
제 메일 주소로 운영자님 메일 주소 알려주시면 소스코드 보내드릴께요...
메일 webmember _at_ paran _dot_ com
아니면, 소켓으로 직접 송수신 한는 부분을 포함해서 도움을 받을수 있을까요???
아무리봐도 제가 어디를 놓쳣는지 몰르겟네요...



최근 덧글