강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

김성수님의 프로필 이미지
김성수

작성한 질문수

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버

Packet Generator #6

전체 정리 중 이해가 어려운 부분이 있습니다 ㅠ

해결된 질문

작성

·

369

3

제가 이해력이 부족해서 계속 정리해보고 넘어가느라 자꾸 질문을 드려서 죄송합니다...ㅠㅠ

전체적인 틀이 궁금한데 서로 연결이 되는 부분이 이해가 잘 안되었습니다!

메일로 사진 첨부하여 보내드렸습니다!

1. 아래와 같이 이해를 해도 될까요?? 혹시 틀린 부분이 있다면 알려주세요!

2. Socket 안에 Buffer가 들어있는 개념일까요? 아니면 Buffer를 개별로 따로 봐야할까요??

3. Buffer = Queue 가 맞을까요??

4. 결국에 이런 스크립트를 작성하는 이유는 서버와 클라이언트가 '패킷'을 주고 받는 것이 궁극적 목표인가요?

5. 4번의 목표(패킷의 송수신)를 좀 더 간편하게 하기위해 packet Generator를 한게 맞을까요?

6. packet 직렬화를 하지 않고는 패킷 송수신이 불가능 할까요(바이트 단위로 변화하는 작업은 필수 일까요??)?? 

7. packet Manager에서 OnSendPacket가 필요 없는 이유를 알 수 있을까요??

항상 감사드립니다..

답변 1

7

Rookiss님의 프로필 이미지
Rookiss
지식공유자

1. 아래와 같이 이해를 해도 될까요?? 혹시 틀린 부분이 있다면 알려주세요!

대부분 맞는데 port는 사람 이름이라기 보다는
정문 위치(주소)에 더 가깝습니다.
그리고 버퍼=Queue는 아닙니다.

2. Socket 안에 Buffer가 들어있는 개념일까요? 아니면 Buffer를 개별로 따로 봐야할까요??

Buffer는 별개로 봐야 합니다. Socket은 휴대전화처럼 진짜 상대방이랑 통신하기 위한 도구이고,
Buffer는 말 그대로 데이터를 '임시 저장'하는 용도로 사용되는 메모리 저장소를 의미합니다.
Buffer는 우체통에 비유하면 적절합니다.
편지를 보낼 때 우리가 바로 우체국에 보내는 것이 아니라,
우체통에 넣으면, 나중에 우편 배달부가 수거해가겠죠.
반대로 우편 배달부가 우리한테 직접 찾아와 편지를 직접 주기 보다는,
우체통에 넣고 갈 것입니다. 이런 임시 공간으로 생각하시면 되겠습니다.

3. Buffer = Queue 가 맞을까요??

Buffer는 그냥 임시 저장하는 공간입니다.
아마도 SendBuffer에서는 SendBufferQueue를 만들어서 조금 혼동이 되시는 것 같네요.
비유하자면 이렇습니다. 우편함에 우편을 10통 넣으면,
그 10통을 우편함에 먼저 넣은 순서와 상관없이 뒤섞여서 도착할 수 있겠죠.
하지만 게임에서 패킷은 우리가 실제 보낸 순서 그대로 상대방에서 받기를 원합니다.
(데미지 100을 입었다 -> 죽었다) 패킷 순으로 와야지,
(죽었다 -> 데미지 100을 입었다) 순으로 도착하면 조금 앞뒤가 안맞겠죠?
따라서 순차적으로 패킷을 보내기 위해,
(그리고 Buffer가 다 찼을 경우 잠시 대기하는 용도 등을 위해)
Queue를 이용해 실제 보내야할 패킷들을 잠시 들고 있는 것입니다.
넓은 범위로 생각하면 이것도 일종의 버퍼라고 볼 수 있긴 하지만
항상 버퍼 = 큐는 아니죠. (RecvBuffer는 딱히 Queue를 활용하지도 않았습니다)


4. 결국에 이런 스크립트를 작성하는 이유는 서버와 클라이언트가 '패킷'을 주고 받는 것이 궁극적 목표인가요?
네 그렇습니다.

5. 4번의 목표(패킷의 송수신)를 좀 더 간편하게 하기위해 packet Generator를 한게 맞을까요?
그렇습니다. 정확히는 패킷 직렬화/역직렬화 작업을 쉽게 하기 위함입니다.

6. packet 직렬화를 하지 않고는 패킷 송수신이 불가능 할까요(바이트 단위로 변화하는 작업은 필수 일까요??)?? 

물론 직렬화는 필수적입니다.

class Item
{
/// ... 데이터
}

class Knight
{
 
Item _item = new Item();
}

위 예제에서 new Knight()를 이용해 Knight 객체를 만든다고 생각해보세요.
그러면 내부적으로 _item이라는 Item 타입의 참조값을 들고 있을겁니다.
하지만 참조값(즉, 주소값)은 프로그램을 새로 실행할때마다 바뀌는 것이고,
곧이 곧대로 이 주소값을 상대방에게 보낸다면
상대방은 그 주소값이 무엇을 의미하는지 이해할 수가 없습니다.
즉 모든 데이터를 상대방이 이해할 수 있게 변환하는 것은 필수적입니다.

7. packet Manager에서 OnSendPacket가 필요 없는 이유를 알 수 있을까요??

OnRecvPacket은 상대방이 직렬화해서 보내준 데이터를 역으로 메모리 상의 데이터로 변환하기 위해 만든 것입니다. 우선 직렬화된 데이터의 프로토콜 번호를 보고, 어떤 패킷에 해당하는지를 찾아서 만들어줘야 하기 때문에 조금 복잡한 과정을 거친 것입니다.
반대로 보내는 입장에서는 메모리 상의 데이터를 직렬화 하는 작업을 해줘야 하는데, 이때는 이미 어떤 패킷인지가 명확하니 굳이 OnSendPacket과 같은 별도의 단계를 거칠 필요 없이 바로 Write를 이용해 변환을(직렬화를) 해주면 됩니다.

김성수님의 프로필 이미지
김성수

작성한 질문수

질문하기