반응형

C# Socket : 고정 구조체 만들기

알게된 배경

 C++로 작성된 서버 혹은 PC와 통신을 하기 위해서는 일반적으로 고정된 크기의 Head와 고정 혹은 가변의 Body로 나누어서 통신을 하는 경우가 많다. C/C++에서는 Struct를 고정된 크기로 할당하는 것이 가능한 반면 C#에서는 별도의 코딩이 필요로 하다.

 이는 기본적으로 C#에서는 배열을 new 키워드를 통해서 정의 및 초기화를 했기때문에 struct에서는 사용이 불가능하다(반면 클래스에서는 사용가능하다).


C/C++의 고정 Struct

 그냥 배열로 선언을 해주면 된다. 아래의 SHead의 크기는 대략 40바이트가 된다. C에서는 그냥 선언해주면 되지만, C++의 경우에도 컴파일에 따라서 추가 선언을 해줘야 한다. C++에 대해서 추후 링크를 추가한다.

// head.hpp
struct SHead
{
    char name[8];
    unsigned char headType;
    char hostname[31];
};



C# unsafe

지금은 폐지된 방법이다. 초기에 불편하자 급조한 티가 난다. 참조문서는 지금도 가이드라인에 있다. 폐지된 만큼 가이드 라인에 맞게 작성해도 에러로 표시된다. 폐지된 방법은 아니고 컴파일 옵션에서 안전하지 않은 코드 컴파일 설정을 바꿔서 실행할 수 있다. C 스타일의 코딩을 자주 해야 한다면, 컴파일 옵션을 풀고 작성하는 것이 코드가 더욱 간결하다. 하지만, 키워드에서 알 수 있듯이 안전하지 않다. (그리고 마소에서 쓰지 않도록 하려고 일부러 쓰기 어렵게 만들어 놓은 방법이기도 하다)


 unsafe가 위험한 이유는 GC가 unsafe로 선언된 곳은 메모리 해제를 하지 않는다.

namespace sock
{
    public struct unsafe SHead
    {
        public Byte fixed name[8];
        public Byte headType;
        public Byte fixed hostname[31];
    }
}




C# Marshal

권장하는 방법이다. 시그니처를 이용해서 배열의 크기를 정해주는 방식이다. 사용하기 위해서는 using System.Runtime.InteropServices; 를 선언하거나 전부 적어주면 된다. pack 옵션 값은 메모리 처리 방식을 할때 단위를 1바이트로 하겠다는 의미이다.

 이러한 키워드를 추가 하지 않으면, 시스템마다 차이는 있지만, 기본적으로는 8바이트를 기준으로 처리를 한다.

namespace sock
{
    [Structlayout(LayoutKind.Sequential, pack=1)]
    public struct SHead
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public Byte[] name;
        public Byte headType;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 31)]
        public Byte[] hostname;
    }
}



 여기서 C#에서 취급하는 특징을 보면 메모리에 배열처럼 연속으로 올릴 경우를 안전하지 않은 방법으로 취급하기 때문에 여러 번거로움이 있다. 이렇게 번거롭게 만든 이유는 가능하면 사용하지 말라는 의도가 있다는 것으로 보인다. 그래도 소켓 프로그램 쪽에서는 어쩔 수 없이 사용해야 하는 경우가 있다.

잡설

 따지고 보면 C#에서 제공하는 두가지 방법들 모두 해당 자료가 안전하지 않다는 것을 명시해주는 것이다. 속도 같은 효율도 떨어진다는 건 덤.. 이러한 이유로 C로 프로그램을 작성할 경우 시스템 이해도와 잘하는 사람과 못 하는 사람간의 차이가 심하다.


참조자료

가이드 라인 unsafe

가이드 라인 unsafe 모드 컴파일

MASN문서 Marshal Array

MSDN문서 LayoutKind

블로그 :고정크기 사용방법




반응형
반응형

Linux CentOS 7 : 고정IP 설정

알게된 배경

 서버를 구축하고 사용하려 하다 보면 IP관리를 위해서 고정 IP는 필수로 설정하게 된다. 가장 이상적인 방법은 CentOS7부터는 설치할때 GUI에서 설정할 수 있으니 가능하면 이때 설치를 해놓으면 좋다. 하지만, 관리하다 보면 변동 사항이 있을 수도 있으니 정리해 놓자


고정 IP 설정 파일 위치

cd /etc/sysconfig/network-scripts
vi ifcfg-eth0

vi 사용법을 모른다면, 다른 편집기를 사용해도 된다.

 여기서 파일은 과거에는 ifcfg-eth0이지만, 설치할때 디바이스를 뭘로 잡았느냐에 따라서 ifcfg-뒤의 이름이 다르다. 때문에 ls를 입력하여 어떤 파일이 있는지 확인해야 한다. wlan0 같은 이름을 가진 파일은 와이파이 디바이스니 설치할때 뭘로 했었는지 기억을 떠올리던가 기록을 해둔것을 찾아서 수정해야 한다.


 대략 많은 내용의 설정파일들이 다음의 내용을 수정하고 없으면, 추가를 해서 작성하면 된다.

BOOTPROTO=static
IPADDR=XXX.XXX.XXX.XXX
NETMASK=XXX.XXX.XXX.XXX
DNS2=XXX.XXX.XXX.XXX
GATEWAY=XXX.XXX.XXX.XXX
DNS1=XXX.XXX.XXX.XXX

 수정이 끝났으면, vi의 경우 저장하고 종료한다음에 리부트(reboot)하거나 디바이스를 재시작 해주면 된다.


각 필요한 항목에 대한 설명은 다음과 같다.


 BOOTPROTO

 static이면 고정, dhcp이면 유동(자동), none이면 사용안함

 IPADDR

 고정(사용)할 IP주소 

 NETMASK

 네트워크 제공쪽 넷마스크(공유기의 내부망 정보 참조)

 국민 공유기인 iptime 제품 경우 255.255.255.0 이 기본 설정이다.

 DNS2

 보조DNS 서버(공유기 혹은 모뎀에서 확인가능)

 GATEWAY

 네트워크 제공자(공유기 혹은 모뎀)

 DNS1

 DNS 서버(공유기 혹은 모뎀에서 확인가능)


나머지는 네트워크 디바이스에 관한내용이기 때문에 다음에 다루던가 네트워크 쟁이들에게 물어보자.


참조 자료

고정IP 설정 메모된 블로그


반응형

+ Recent posts