개인공부) 서버실습(28) - SendBuffer

Justin·2022년 6월 20일
0

서버공부

목록 보기
27/45

✅ 지난시간

Receive Buffer를 제작하여 하드 코딩식이 아닌, 패킷 처리가 됐을 때도 적용 가능하도록 틀을 구성하였다.

기존 Send는 Encoding 하여 byte타입으로 넘겨주고, SendQueue에 저장하며 처리하는 방식이었다. 이번에는 이 부분을 개선 해줄 것이다.

❓ Receive와 차이점

하지만 Receive와 가장 큰 다른점은 Recv는 Session 마다 하나씩을 가지고 있어 사용 및 관리가 용이했다면, Send는 내부에서 적용하게 될 경우 성능 이슈가 발생한다.

Ex) 실시간 게임에서는 1명이 움직이면 나머지에게 이동 패킷을 전송을 해주게 되는데, Receive 같이 하나 씩 생성하면 100명이 동시에 움직일 경우 100*100으로 거의 10,000번 가까이 새로 생성해야하지만, 외부에서 선언 해줄 경우 생성한걸 loop로 넘겨주기만 하면 되기에 생성을 하는 것 보다는 훨씬 성능적으로 이득을 볼 수 있다.

🕳 Buffer Size 설정

보내 줄 때 마다 몇 바이트를 사용할 것인지 결정해서 보내주면 좋지만, String 값 같은 경우는 변경될 수 있기에 고정으로 보내기에는 어렵다.

그렇기에 큰 값을 선언해두고, 그 중 일부를(ArraySegment) 사용하는 방식으로 구성할 예정이다.

🌐 제작

buffer로 활용해줄 byte 배열과, RecvBuffer에서 writepos와 같이 현재 사용한 영역을 표기할 usedSize, 그리고 남은 공간의 크기를 나타내는 FreeSize를 선언해준다.

🌞 Open

사용하고자 하는 공간 만큼의 버퍼를 요청하고, 가능하면 뱉어주고, 아니면 넘겨주지 않는 구조로 구성한다.

🌚 Close

Open이후 사용한 사이즈 만큼을 받아와서, 지정해준 뒤에 다시 뱉어주어 정확한 사용량을 체크하여 _usedSize에 대입한다.

❓❔ Recv Buffer와 차이점 2

Sendbuffer는 클린이라는 개념이 없다. send를 여러명에게 보내기에 다른 누군가가 sendQueue에 담아두고 참조하고 있을 수 있기에 재사용 구조를 만들기는 어렵다.(1회용)

🗃 TLS를 활용한 Helper Class

SendBuffer의 내부 함수는 건들지 않고 사용하기 위해 SendBufferHelper라는 새로운 Class를 만들고, 사용하기 쉬우면서 고유의 영역을 가질 수 있는 TLS(ThreadLocalStorage)를 만들어준다.

ChunkSize(덩어리) 라는 큰 덩어리를 생성하여 다 사용할 때 까지 쭉 사용할 공간을 만든다.

🔸 TLS의 Open

이 부분에서도 Open, Close 를 활용할 수 있도록 제작하고, Open 시에는 TLS의 Value 값 체크로 아직 생성하지 않았다면, 새로운 공간을 만들어주고

남은 공간(FreeSize)가 새로 요청한 공간 보다 작을 경우. 즉, 여유 공간이 없을 경우에도 새로운 buffer를 만들어서 날려준다.

물론 두 조건에 걸리지 않고, 여유공간이 있을 때는 TLS의 Value의 Open을 해주며 전에 만든 곳에 사이즈를 넘겨준다.

🔸 TLS의 Close

사용 후에는 크게 제약사항이 없기에 바로 넘겨준다.

📲 Session의 Send

이제 아래와 같이 직접 SendBuff를 만들어 넘겨주는 영역을 수정 할 것이다.

byte[] sendBuff = Encoding.UTF8.GetBytes("Welcome to Justin Server")

예시를 위해서 새로운 Class의 hp, attack 데미지 등을 추가하고, 값을 넣어준다.

SendBufferHelper.Open(4096)을 사용하여 Chunk 사이즈의 ArraySegment를 생성하고

BitConverter.GetBytes() 를 사용하여 hp, attack에 담아준 100과 10이라는 값을 byte[] 타입으로 변환한다.(둘은 각 4bytes를 할당한다)

Array.Copy()로 큰 공간을 만들어둔 openSegment에 복사해서 넣어준다. offset 값은 잘 맞춰주어야 하나 들어가고 그 다음 부터 들어간다.

그 뒤 사용한 만큼(buffer1, 2의 Length)을 알려준 뒤 Close를 해주고, 그 배열을 Send 해주면 8바이트가 넘어온 걸 알 수 있다.

profile
인디 게임을 만들며 공부하고 있습니다.

0개의 댓글