5.메시지 객체(Proud.CMessage)

Edit

ProudNet의 내부에서는 메시지 객체를 다루기 위해 Proud.CMessage 객체 타입을 사용합니다.일반적으로 4. Remote Method Invocation (원격 메서드 호출) 을 사용하는 경우에는 Proud.CMessage를 쓸 일이 거의 없습니다.

Proud.CMessage는 고성능의 데이터 스트림 객체입니다.데이터 스트림을 통해서 사용자는 여러가지 데이터를 한 개의 데이터 블럭에 저장하거나 불러오기를 손쉽게 할 수 있습니다.

Proud.CMessage는 메모리 버퍼를 참조합니다.메모리 버퍼는 Proud.CMessage 객체가 소유한 내부 메모리 블럭이 될 수 있으며(이를 internal buffer 내부 버퍼라 합니다) Proud.CMessage가 직접 소유하지 않고 다른 메모리 블럭을 참조할 수 있습니다.(이를 external buffer 외부 버퍼라 합니다.) Proud.CMessage 객체를 다루려면 Proud.CMessage 객체 생성 후 Proud.CMessage.UseInternalBufferProud.CMessage.UseExternalBuffer로 사용할 메모리 버퍼를 결정해야 합니다. 메모리 버퍼를 결정한 후에 또 다른 메모리 버퍼를 참조하게 하려면 사용하던 메모리 버퍼를 먼저 초기화해야 합니다. 초기화는 Proud.CMessage.UninitBuffer로 할 수 있습니다. 메모리 버퍼 지정에 관한 예는 메시지 버퍼 선택하기를 참조하십시오.

보통의 경우 내부 버퍼를 사용하면 됩니다.하지만 이미 어디선가 메시지로 읽을 데이터 블럭이 준비된 경우 그것으로부터 Proud.CMessage 객체가 따로 복사를 한 후 읽어들이는 것 보다는 그 블럭을 직접 참조해서 읽어들이는 것이 성능상 좋습니다.이러한 경우가 외부 버퍼를 사용할 수 있는 예입니다.

Proud.CMessage 가 내부 버퍼를 사용할 경우 메시지 최대 크기는 Proud.CNetConfig.MessageMaxLength 입니다.외부 버퍼를 사용할 경우 외부 버퍼의 크기만큼으로 제한됩니다.메시지의 크기는 Proud.CMessage.SetCount 로 지정할 수 있습니다.

Proud.CMessage.WriteProud.CMessage.Read를 통해 메시지 객체에 데이터를 읽거나 쓸 수 있습니다.메시지 객체는 데이터 스트림이기 때문에 기록을 할 때마다 계속해서 길이가 늡니다.Proud.CMessage 내부에는 현재 읽기 지점(read offset)이 있습니다.데이터를 읽어들일 때는 읽기 지점 값이 증가합니다.읽기 지점은 Proud.CMessage.SetReadOffset으로 강제 변경할 수 있습니다.

그림 5-1메시지 객체 타입

5.1메세지 객체의 기본적 사용법

Proud.CMessage를 다루는 기본적인 예는 아래와 같습니다.

int a = 1;
Proud::String b = L"abc";
double c = 3.3;†
char d[100];
Proud::CMessage msg; // 메시지 객체 생성
msg.UseInternalBuffer(); // 내부 버퍼를 사용하도록 지정한다.†

msg.Write(a); // int 타입 변수를 msg 객체에 넣는다. 이때 메시지의 크기는 sizeof(int)만큼 증가한다.
msg.WriteString(b); // 문자열 타입 변수를 msg 객체에 넣는다. 이때 메시지의 크기는 문자열 길이 이상 증가한다.
msg.Write(c); // 마찬가지
msg.Write(d, 100); // 100바이트 메모리 블럭을 msg 객체에 넣는다.

msg.SetReadOffset(0); // 현재 읽기 지점을 맨 앞으로 옮긴다.

msg.Read(a); // 도로 읽는다
msg.ReadString(b); // 마찬가지
msg.Read(c); // 마찬가지
msg.Read(d,100); // 100바이트 메모리 블럭을 읽는다.

// 앞에서 기록한 내용과 읽은 내용이 동일하므로 읽기 지점과 메시지의 길이가 동일할 것이다.
assert(msg.GetReadOffset() == msg.GetCount());

Proud::CMessage msg2; // 또다른 메시지 객체
msg2 = msg; // 원본을 복제한다.

5.2메세지 객체의 기본적 사용법(<<,>> 연산자 사용)

_basic_usage

Proud.CMessage와 <<, >> 연산자를 혼용할 수 있습니다.

<< 연산자는 메시지 객체에 데이터를 이어넣을 때, >> 연산자는 데이터를 하나씩 꺼낼 때 씁니다.

int a = 1;
Proud::String b = L"abc";
double c = 3.3;

Proud::CMessage msg;
msg.UseInternalBuffer();

msg << a << b << c;   // a,b,c 순서대로 메시지 객체에 저장
msg >> a >> b >> c;   // a,b,c 순서대로 메시지 객체로부터 꺼내기

5.3메세지 버퍼 선택하기

다음은 내부 또는 외부 버퍼를 사용하는 예입니다.

char a[100]; // 외부 버퍼
Proud::CMessage msg; // 메시지 객체
msg.UseExternalBuffer(a,100); // 외부 버퍼를 사용하되 사용 가능한 최대 크기도 노티한다.

msg.SetCount(3); // 외부 버퍼를 사용하지만 메시지 객체 내부에는 현재 3바이트만큼의 데이터가 들어있음을 설정한다.
msg.SetCount(101); // 외부 버퍼의 크기를 넘어갔으므로 예외가 발생함

Proud::CMessage msg2; // 또다른 메시지 객체
msg2 = msg; // 원본을 복제한다. 이때 msg와 msg2는 같은 외부 버퍼를 참조한다.

메모리 버퍼를 이것 저것 사용하는 예는 다음과 같습니다.

char a[100]; // 외부 버퍼

Proud::CMessage msg; // 메시지 객체
msg.UseExternalBuffer(a,100); // 외부 버퍼를 사용하되 사용 가능한 최대 크기도 노티한다.

msg.SetCount(3); // 외부 버퍼를 사용하지만 메시지 객체 내부에는 현재 3바이트만큼의 데이터가 들어있음을 설정한다.

msg.UninitBuffer(); // 메모리 버퍼 사용을 취소하고 상태를 초기화
msg.UseInternalBuffer(); // 내부 메모리 버퍼를 사용하도록 지정