혹시 직렬화 라이브러리 사용하는게 있나요?

3권에서 새로 도입된 네트웍 및 멀티플레이어 프로그로그래밍 섹션을 위한 게시판입니다.

Moderator: 류광

Locked
ikpil
Posts: 98
Joined: 2008-11-12 21:17

혹시 직렬화 라이브러리 사용하는게 있나요?

Post by ikpil »

안녕하세요?

직렬화 라이브러리(serialization lib.) 가 무엇인지는 생략을 하고,

네트워크 패킷을 보낼 때 OBJECT 를 직렬화 라이브러리를 이용하여, 직렬시키고, 전송하시는 분이 계신가요?

저같은 경우 다음의 문제가 생겼습니다. 아참 저는 boost::serialize 를 사용 했습니다.

첫째, 헤더에 바디의 사이즈를 넘겨야 하는데, 바디의 사이즈를 모름
둘째, 직렬화 시킨 데이터를 메모리로 만들기가 힘듬( ostream, istream 을 상속해서 무엇인가 만들어 줘야 될거 같습니다)

다음의 문제를 직면하게 되니, 네트워크용으로는 부적합하다는 생각이 들었는데,

혹시 네트워크용으로 직렬화 라이브러리 사용하는게 있나요?
아니면 이 문제를 해결 할 수 있는 방법을 알고 계시면 알려 주실수 있으시나요?

ps.
google protocol buffer 도 해봤는데, 이건 네트워크로 쓰기엔 더 안좋은거 같습니다.
baboruri
Posts: 20
Joined: 2008-12-09 10:12

Post by baboruri »

안녕하세요.

얼마전에 보았던 C# Network서적에서 최익필님이 말씀하신 내용에
그나마 근접한 내용이 있기에 간단하게 글을 남겨 봅니다.

너무 간단하기 때문에 큰 도움은 될 것 같지 않네요..

Code: Select all

// C#역시 직렬화를 위해 제공하고 있는 라이브러리가 있습니다.
      IFormatter formatter = new SoapFormatter();
      MemoryStream tmpStream = new MemoryStream();

// 직렬화한내용을 byte에 담아두고
      formatter.Serialize( tmpStream, [직렬시킬데이터] );
      byte[] data = tmpStream.GetBuffer();

// 길이를 바이트로 컨버팅.
      int len = (int)tmpStream.Length;
      byte[] size = BitConverter.GetBytes( len );

// 그리고 순서대로 전송.
      sendStream.Write( size, 0, 4 );
      sendStream.Write( data, 0, len );
      sendStream.Flush();
      tmpStream .Close();
이상입니다~
Smile :)
ikpil
Posts: 98
Joined: 2008-11-12 21:17

Post by ikpil »

현재 상태에선 메모리쪽으로 입출력 할 수 있으며, 사이즈를 알 수 있도록 C++ stream 을 상속해서 만들 수 밖에 없는 것일까요?

C#의 처리를 보니까, 딱 이렇게 하네요.

1. 메모리 공간 확보
2. 확보된 메모리에 직렬화 데이터를 밀어 넣음
3. 1번을 전송


간단해서 이해를 빨리 할 수 있었습니다. 감사합니다.
baboruri
Posts: 20
Joined: 2008-12-09 10:12

Post by baboruri »

제가 최익필님의 글을 맞게 이해하였다면?

굳이 cpp stream을 상속해서 만들지 않아도,
ostream, istream 의 메서드를 이용해서
길이는 알아낼 수 있지 않은가요!?
어찌어찌 좋지 않은 방법으로 버퍼? 도 얻어 낼 수는 있네요.
Smile :)
ikpil
Posts: 98
Joined: 2008-11-12 21:17

Post by ikpil »

맞게 이해 하셨습니다.
현재 표준스트림 지원이 파일 스트림, 표준입출력 스트림, 스트링 스크림만을 지원하는것으로 알고 있습니다.

1. 위의 경우에 객체 직렬화를 메모리에 하기 위해서
파일 스트림은 못쓰고

표준입출력도 못쓰고 ( 이 녀석으로는 할 수 있다해도, 길이를 제는 방법을 모르겠네요)

스트링 스트림도 못쓰는데,

길이를 알 수 있는 방법이 있나요?
ikpil
Posts: 98
Joined: 2008-11-12 21:17

Post by ikpil »

글 쓰고 나니까 이런 방법이 있을꺼 같네요

1. 바이너리를 base64로 인코딩하고, 스트링 스트림으로 출력 후, 그 스트링 스트림으로 길이를 제고, 스트링 스트림을 발송.
baboruri
Posts: 20
Joined: 2008-12-09 10:12

Post by baboruri »

조금 번거로운 방법?이기는 하지만.

ostream, istream역시
ofstream이나 ifstream에서 지원하듯
seek를 이용하면 포인터를 이동하는 방법으로 길이를 알아 올 수 있습니다.

이걸 물어보신게 맞는지요?
맞다면 스탠다드라이브러리템플릿의 iosteam부분을 살펴보시면
예제를 찾으실 수 있을 것입니다.
Smile :)
ikpil
Posts: 98
Joined: 2008-11-12 21:17

Post by ikpil »

ostream 과 istream는 기본 생성자가 없습니다.
그래서, 그냥 써먹을 순 없고, std::streambuf 를 함께 넣어 주어야 하는데

std::streambuf 경우 생성자가 protected로 되어 있기 때문에, 상속을 통하지 않으면, 사용 할 수가 없습니다. STL에선 미리 파일버퍼와 스트림버퍼를 상속하여 미리 만들어 둔 상태입니다.

하지만 이 두개를 사용하여 길이를 재거나, 발송하기가 힘듭니다.((패킷이 날라 올때마다 파일 입출력해서 길이를 젤순 없고, 바이너리를 매번 스트링으로 인코딩 디코딩 할 순 없고)

지금까지 물어 본건
1. boost::serialize에서 직렬화 대상의 최종 사이즈를 알 수 있는 방법이 있는가?

2. boost::serialize에서 직렬화 대상을 메모리에 바로 쓸 수 있는 방법이 있는가?

였습니다. : )


간만에 STL 소스 보니, ... 뭐가 몬지 모르겠네요 : )
관심갖아 주셔서 감사합니다.
cchcc
Posts: 4
Joined: 2009-10-20 18:02

Post by cchcc »

네트워크 때문에 그러신거면
아래 제가 비회원으로 질문올렸었던건데
윈도는 WSASend 유닉스는 writev를 쓰시면
직렬화 따로 안시켜도 됩니다

파라매터만 잘 채워넣으면 알아서 직렬화 시켜서 보내주므로
memcpy비용도 안들어가고 훨 좋아요
softpark
Posts: 4
Joined: 2009-11-20 12:20

Post by softpark »

오브젝트의 패킷의 직렬화.. 질문자체가 매우 맘에 들고 와닿습니다.

저의 생각은.. (경험상.) 직렬화 처리가 간편하더군요..

직렬화 처리의 한예로.. MFC 의 Serialize( operator <<, >>를 따로 구분해

Load, Save 함수), Unreal Engine 의 직렬화를 참고 하시면,

도움이 되실지 모르겠네요..(구글링 검색이 될듯합니다.)

저도, 서버 엔진단에서, 직렬화를 사용고. 만족하고 있습니다
Locked