메시지 기반 네트워크 프로토콜
프로그래밍 :
2005/10/30 23:02
| 프로토콜이라고 했지만.. 뭐 그다지 대단한건 아니고.. 네트워크 프로그램을 짜다보면 데이터를 패킷 이라는 단위의 구조체로 넘긴다. 또한 이런 패킷들은 TCP의 구조상 맨 처음에 패킷의 길이가 들어가야지만 패킷이 전부 도착했는지 안했는지를 알 수 있다. 대충 아래와 같은 형식으로 패킷을 만들게 된다. typedef struct tagPACKET { //패킷의 헤더부분 int size; int type; //패킷의 본문 char chatmessage[128]; }PACKET; 이런 구조체 방식의 패킷은 기본적으로 바이너리 형식이며 따로 파싱 과정이 필요가 없기 때문에 속도 또한 메시지 방식보다는 빠르다. 다만 단점은 디버깅이 쉽지 않다는 점과 서버와 클라이언트를 저 패킷으로 재컴파일을 하지 않으면 굉장히 대략 난감한 시츄에이션이 발생하여 삽질을 하게 된다는 점과 재컴파일의 압박이 심하다는 것이다. 아래는 메시지 방식 패킷의 대략적인 형태이다 1 10 attack monter 3 by with; 2 10 move 100 200 to 120 200 by run; 이런식이다. 처음에 나오는 숫자는 패킷의 시퀸스 넘버이며 두번째는 자신의 id, 그리고 뒤에는 명령어가 오며 그 뒤에 그 명령어에 필요한 인자들이 오는 형식이다. 잘 보면 DBMS의 쿼리문과 비슷하다. 이를 잘 처리 하기위해서는 이를 파싱하는 파서와 각각의 명령어에 따라서 처리가 가능하도록 이를 잘 분기 시켜주는 오토마타 같은게 있으면 된다. 구조체 형식의 패킷보다 이런 메시지 방식의 패킷의 크기가 대략 커지겠지만.. 오히려 최적화가 가능하다. 예를 들어서 총알을 발사하는 패킷이 있다고 하면 이를 총알이 날아갈 때 마다 저런 메시지를 발생시켜서 날리면 대략 난감하다-_-); 그렇다고 구조체로 날린다고 해도 그다지 좋은 방법은 아니다. 따라서 어느정도 시간단위로 발사된 총알의 개수를 필드에 넣어주면 좋다. 하지만 만약에 한번에 한발밖에 안나가는 샷건 같은 경우에는 총알 개수 필드는 필요가 없다. 한발 쏘는데 걸리는 시간이 매우 길기 때문이다. 하지만 기관총 같은 경우에는 총알 개수 필드가 있어야 한다. 이때 구조체 형식의 경우에는 최적화를 위해서는 구조체를 두개를 선언 하고 타입도 다르게 주어야 한다. 대략 압박이다. 하지만 메시지 방식의 경우에는 메시지의 조합이기 때문에 이런 문제가 생기지 않는다. 왜냐하면 필요 없으면 해당 필드를 기술하지 않으면 되기 때문이다. 대략 다음과 같은 형식이다. 1 10 attack monster 3 with shotgun; 2 10 attack monster 3 with dododogun count 3; 이런식이면 패킷의 확장도 매우 쉽다. 필요하면 그냥 뒤에 붙이면 되니 때문이다. 또한 한개의 명령어의 인자들은 순서를 가질 필요도 없다. 아래가 그 예시이다. 1 10 attack with shotgun monster 3; 동일 1 10 attack monster 3 with shotgun; 메시지의 파싱은 한 명령어가 끝난 후에 끝나기 때문에 인자들이 자신의 규약을 지키고만 있다면 어디에 위치해도 문제가 되지는 않는다. 프로그래머는 편한대로 메시지를 만들고 전송하면 된다. 하지만 이러한 유연한 점이 오히려 악이 될수도 있다. 예를들면 어떤 프로그래머는 위 예시의 첫번째 형식으로 메시지를 만들었는데 같이 일하는 다른 프로그래머는 두번째 형식으로 메시지를 작성했다면 나중에 유지보수가 힘들어진다는 것이다. 이런 메시지 기반의 패킷은 이미 우리가 잘 쓰고 있는 msn과 nateon에서 사용 하는 방식이다. 그렇지만 이런 텍스트기반의 메시지는 쉽게 패킷의 내용을 볼 수 있어서 해킹에 취약하다. 이를 막기 위해서는 또한 간단하다. 그냥 압축을 하기만 해도 어느정도는 감출 수 있다(물론 압축의 경우에는 이미 이건 메시지가 아닌 바이너리 형식으므로 앞에 압축한 만큼의 사이즈를 줘야만 받는 쪽에서 어디까지가 압축된 것인지 알고 압축을 해제하게 된다. 압축이 해제 되면 그 후로는 일반 텍스트를 파싱하듯이 하면 된다.). 또한 패킷의 시퀸스 같은 것을 관리하면 더 좋다. 물론 더 복잡 하게 할려면 자체 암호화도 필요하겠지만 말이다. 이런 메시지 방식의 패킷의 가장 큰 장점은 디버깅이 쉽다는 점과 쉽게 확장이 가능하다는 점. 그리고 꼭 서로 최신 패킷으로 업데이트를 하지 않더라도 호환성이 보장이 된다는 점이다. 단점이라면 패킷의 크기가 커지는 점과 구조체 보다는 패킷을 더 쉽게 분석이 가능하다는 점과 메시지의 파싱 과정이 더 필요하다는 점이다. 하지만 메시지 파싱 과정은 요즘 컴퓨터의 성능상 그다지 큰 문제가 되지 않는다고 생각한다. 파싱 후 명령 분기 또한 명령 테이블을 이용하면 log시간내에 분기도 가능하니 말이다. 패킷의 크기가 커지는 것은 패킷을 압축을 하면된다. 구조체 형식도 사실 암호화를 위해서 또는 크기를 줄이기 위해서 압축을 하기 때문에 압축이라는 또하나의 과정을 가지는것은 아니다. 텍스트이기 때문에 꽤나 높은 압축율이 높아 구조체와 그다지 큰 차이를 보이지도 않는다. 그리고 패킷이 분석이 쉽다는 것은 구조체보다는 쉽지만 암호화를 하면 구조체 못지 않게 난해하게 만들 수 있다. |





댓글을 달아 주세요