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

작성자 없음

작성자 정보가 삭제된 글입니다.

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

PacketSession

Buffer와 Packet에 관한 의문

작성

·

540

0

안녕하세요 ㅎㅎ

강의를 들으며 세세한 것 보다 전체적인 흐름을 잘 이해하려고 노력중입니다. 몇 가지 흐름을 파악하다 의문이 생겨서 질문 드립니다.

Q.1 PacketSession 클래스의 OnRecv함수입니다.

while문의 첫번째 if문을 보면 일단 헤더의 size는 파싱할 수 있는지 체크를 하고 있는데요, 잠시 TCP의 성질을 보면

TCP통신의 경우 혼잡제어를 통해 서버가 혼잡하면 일부만 보내고 다시 원활해지면 나머지를 보낸다고 하셨습니다.

그렇다면 혼잡시에 패킷의 일부만 전송되어 SIZE만 보내진다거나 헤더를 제외한 데이터만 전송되는 경우도 있나요?

일부만 전송한다는 얘기가 패킷단위로 나눠서 보낸다는 말이지 패킷을 쪼개서 보내지는 않는다는 뜻인건가요?

Q.2

100명의 유저가 같은 장소에서 모두 움직이면 10000개의 패킷이 전송될것이고, Send를 호출하는 부분이 데이터 복사와 같은 무거운 작업들이 많이 일어나니 컨텐츠단에서 SendBuffer라는 대용량 버퍼를 만들고 거기에 차곡차곡 넣어서 유저당 한번씩만 전송하도록 하여 총 100개의 패킷만 전송하도록 하는 것이 목적인가요? 제대로 이해했는지 아리송합니다 ㅠㅠ

Q.3 

SendBuffer 클래스가 있고 사용하기 편하게 인터페이스를 뚫어준 SendBufferHelper 클래스가 있는데

애초에 SendBuffer를 사용하는 쪽에서 편하게 인터페이스를 뚫어줄 수도있는데 별도 SendBufferHelper클래스를 사용하시는 이유가 있나요?!!

선생님처럼 Helper Class를 작성하면 단기적으로, 장기적으로 어떤 이점이 있는지 궁금합니다.

아직 이와같은 설계가 너무 낯설어서 많이 배우고 알고싶습니다!

Q.4

SendBufferHelper에서 Open시 요구한 사이즈보다 버퍼 여유공간의 크기가 작으면 new 를 통해 새로운 버퍼를 할당하게 되는데요 이전에 사용하던 버퍼는 누군가 잘 사용하다가 더이상 참조가 없어지면 가비지 컬렉터에 의해서 메모리 정리가 잘 되는건가요?

너무 쿨하게 new로 새로운 메모리 공간을 할당해서 조금 의문이 생기네요.

SendBuffer의 경우 전송후에 더이상 참조할 일이 없기에 가능한 Send만의 특징이겠죠?

답변 4

1

헉 제가 코드를 잘못 작성했네요 ㅠㅠㅠOnRecv의 반환값인 processLen을 체크하는 부분에서 0일때 disconnect를 했는데 0미만일때 disconnect군요

이제 완전히 이해 갔습니다!!!!

정말 감사합니다 ㅎㅎㅎ마저 재미나게 수강하겠습니다

1

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

조건에 걸리는 것은 맞지만, 그렇다고 통신이 끊기지는 않습니다.
TCP 연결은  유지한 채로 그 다음 Recv에 나머지 데이터를 받아올 것이고
이어서 조립 코드가 실행됩니다.
따라서 RecvBuffer에 남은 찌끄레기 데이터를 날리는게 아니라,
복사해두는 것을 알 수 있습니다. (패킷이 분할되어 올 수 있기 때문)

0

답변 감사합니다 ㅎㅎ 1번 질문에 대해서 한 가지만 더 여쭤보겠습니다.

1. 
보내는 입장에서는 신경쓸 필요 없고 보내기로 요청한 모든 내용이 보내져야 함수 완료 통지가 옵니다.
하지만 받는 쪽에서는 패킷이 쪼개져서 올 수 있어서
이론적으로 전송자가 100바이트를 보냈더라도 20바이트를 5번 받을 수 있습니다.

-> 100바이트 패킷[헤더 20bytes 데이터 80bytes]이 있다고 가정했을 때 20 바이트를 5번 받게 되면 

패킷의 첫 20 바이트가 도착 했을 때 아래의 조건문에 걸리게 되고 processLen이 0으로 반환돼서 통신이 끊기게 될텐데.. 이게 일반적인 통신의 형태가 맞는지 궁금합니다.

패킷을 쪼개서 보내고 조립하는건 TCP 프로토콜의 영역이고 문제가 없다면 아래 OnRecv함수에는 온전한 형태의 패킷이 인자로 들어오나요? 

0

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

1. 
보내는 입장에서는 신경쓸 필요 없고 보내기로 요청한 모든 내용이 보내져야 함수 완료 통지가 옵니다.
하지만 받는 쪽에서는 패킷이 쪼개져서 올 수 있어서
이론적으로 전송자가 100바이트를 보냈더라도 20바이트를 5번 받을 수 있습니다.

2.
네 맞습니다.
보낼때마다 패킷을 만드는게 아니라, 
패킷을한 번 만들고 필요한 애들 전체에 뿌리자는 정책입니다.

3.
이런 질문은 딱히 정답이 없는 문제라, 스스로 판단해야 합니다.

4.
물론 GC에 의해 회수됩니다.
다만 지금 당장 우리가 손을 대면 안 되는게,
이미 예약된 Send가 호출 완료 되었는지를 확인할 길이 없기 때문입니다.
나중에 나올 C++ 서버에서는 직접 ReferenceCounting을 통해 해제를 해주게 될겁니다.

작성자 없음

작성자 정보가 삭제된 글입니다.

질문하기