달력

5

« 2024/5 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

PacketSession은 NetworkSession클래스를 상속받음. 데이터만 관리하는 NetworkSession을 상속받아 패킷기능을 추가하는 개념.


패킷이란?

NetworkSession을 통해서 주고받는 데이터를 의미있는 덩어리화 한 것?

메모리 블록 방식    : 주고받는 블록의 최대 크기를 지정해두고, 앞부분부터 일정 크기만큼의 데이터에 역할을 정해두는 방식. 


이 방식에서 쓰이는 패킷의 구조

|----------------------------------------4096 bytes-----------------------------------|

|          4Bytes       ||          4Bytes    ||            4Bytes       ||              4084Bytes            |

|-DWORD(Length)-||--DWORD(UN)--||--DWORD(Protocol)-||----------DATA-----------|

     |------------------------Encryption-------------------------------|


Length    : 전체 패킷의 길이 저장. 

Protocol  : 패킷의 기능.

UN         : 패킷 고유 번호. 클라이언트마다 고유한 번호 전송. 해킹 검증 및 동일 패킷 검증에도 사용.

DATA     : 사용자가 정의 한 데이터. 



CPacketSession() - 생성자. 패킷 버퍼와 관련 변수들을 초기화한다.

- mRemainLength    : mPacketBuffer에 남은 길이. 패킷 처리 후 Nagle알고리즘으로 완성되지 않은 패킷의 남은 길이.

- mCurrentPacketNumber    : 현재 상태에서 상대에게 보내야 할 패킷의 번호.

- mLastReadPacketNumber    : 마지막으로 받은 패킷 번호. 이미 보낸 패킷인지 여부를 검증함.


Begin() - 클래스 시작 함수. PacketSession에서 사용할 WriteQueue 및 상속받은 NetworkSession 클래스 초기화. CNetworkSession클래스의 Begin()을 리턴함.


End() - 큐를 종료하고 CNetworkSession클래스의 End()를 리턴함.

- mLastReadPacketInfoVectorForUdp    : UDP는 TCP와 달리 하나의 개체가 여러 접속을 관리하기 때문에 받은 곳의 정보와 패킷 번호를 이 벡터로 관리한다.

_READ_PACKET_INFO : 위의 벡터가 관리하는 구조체.

->RemoteAddress : 받은 주소 / RemortPort : 받은 포트 / PacketNumber : 패킷번호


WriteComplete() - 보내기 완료 시 큐에서 데이터를 삭제하는 함수. 전송 후 pop을 해줌. 


 

TCP코드


GetPacket() - 받은 패킷을 분석하는 함수. 받은 패킷을 Decrypt한 후 패킷의 길이, 번호 등을 얻는다. PacketSession에서 가장 중요한 역할.

-  패킷의 유효성 검사(크기가 버퍼보다 크거나 0보다 작으면 잘못된 패킷)

- 유효한 패킷일 경우 암호화된 부분을 Decrypt해줌.

- 패킷의 번호와 프로토콜을 받아옴(PacketNumber, Protocol).

- 패킷 처리 후, 남은 길이 확인 및 마지막 받은 패킷 번호 저장 등 실행.


ReadPacketForIocp() - CNetworkSession에서 데이터를 받아오는 함수. NetworkSession 클래스 버퍼에서 PacketSession클래스 버퍼로 데이터를 복사해옴. 이렇게 복사해온 데이터를 GetPacket()함수를 이용하여 패킷형태로써 확인을 하는 순서로 흘러감. ReadPacketForEventSelect도 동일한 흐름.


WritePacket() - 전송할 데이터에 길이, 프로토콜, 패킷 번호등을 넣어 패킷화 하여 보내는 함수. 

- 패킷 길이를 지정( 길이 + 패킷번호 + 프로토콜 + 데이터 ).

- 임시버퍼에 순서대로 써줌( 패킷 길이 + 패킷 번호 + 프로토콜 + 데이터 ).

- 길이를 제외한 나머지 부분을 Encrypt해줌.

- 완성된 데이터를 WriteQueue에 Push해줌.

->WriteQueue에 데이터가 저장된 임시 버퍼의 포인터를 Push하고, 그 리턴값으로 Push된 Data의 포인터를 리턴하여 WriteData에게 넣어줌.

- WriteData를 Write함수를 통해 써줌. 왜 이렇게 포인터를 통해 보내주느냐면, 임시버퍼에 써둔 데이터는 WritePacket함수가 종료됨과 동시에 사라지기때문에, WriteComplete가 일어나기전까지 데이터가 무사할 수 있는 큐에 넣는 방식으로 유지시킴.





:
Posted by 웽웽