PacketBufferManager 클래스
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace csharp_test_client
{
class PacketBufferManager
{
int BufferSize = 0;
int ReadPos = 0;
int WritePos = 0;
int HeaderSize = 0;
int MaxPacketSize = 0;
byte[] PacketData;
byte[] PacketDataTemp;
- 패킷 데이터를 보관하고 전송하기 위해 버퍼 사용?
- 패킷이 생성되고 전송될 때 데이터가 일반적으로 버퍼에 저장되어 네트워크를 통해 전송
Init
public bool Init(int size, int headerSize, int maxPacketSize)
{
// 패킷 사이즈나 헤더 사이즈가 이상할 경우 false 반환
if (size < (maxPacketSize * 2) || size < 1 || headerSize < 1 || maxPacketSize < 1)
{
return false;
}
// 매개변수로 받은 정보들을 클래스변수에 할당
BufferSize = size;
PacketData = new byte[size];
PacketDataTemp = new byte[size];
HeaderSize = headerSize;
MaxPacketSize = maxPacketSize;
return true;
}
- 버퍼 사이즈, 패킷 데이터(바이트 배열) 등 클래스 변수들 값 초기화
Write
public bool Write(byte[] data, int pos, int size)
{
// 데이터가 없거나 길이가 사이즈와 포지션의 합보다 작으면 false 반환
if (data == null || (data.Length < (pos + size)))
{
return false;
}
// 남은 버퍼 사이즈 측정 : 버퍼 사이즈 - 마지막에 쓴 곳 위치
var remainBufferSize = BufferSize - WritePos;
// 현재 남은 버퍼 사이즈보다 써야할 데이터가 크면 false 반환
if (remainBufferSize < size)
{
return false;
}
// data의 값을 PacketData에 복사
Buffer.BlockCopy(data, pos, PacketData, WritePos, size);
// 쓴 만큼 WritePos 위치 증가
WritePos += size;
// 버퍼에 남은 공간이 없으면
if (NextFree() == false)
{
BufferRelocate();
}
return true;
}
- NextFree : 버퍼에 여유 공간이 있는지 확인하는 함수
- BufferRelocate : 버퍼가 가득 찼으면 호출
- 현재 버퍼의 데이터를 새로운 메모리 영역으로 이동시키고, 버퍼의 크기를 확장함
Read
public ArraySegment<byte> Read()
{
// 현재 읽을 수 있는 크기 계산 : 마지막으로 쓴곳 - 마지막으로 읽은곳?
var enableReadSize = WritePos - ReadPos;
// 현재 읽을 수 있는 크기가 헤더크기보다 작으면
if (enableReadSize < HeaderSize)
{
// 빈 ArraySegment를 반환해서 읽을 데이터가 부족함을 나타냄
return new ArraySegment<byte>();
}
// 현재 읽기 위치에서부터 PaketData를 읽어서 16비트 정수로 변환
// 패킷 데이터의 크기
var packetDataSize = BitConverter.ToInt16(PacketData, ReadPos);
// 패킷 데이터의 크기가 현재 읽을 수 있는 크기보다 크면
if (enableReadSize < packetDataSize)
{
return new ArraySegment<byte>();
}
// 완전한 패킷 데이터
// PacketData를 ReadPos부터 사이즈만큼 읽어와서 ArraySegment로 만들어서 반환
var completePacketData = new ArraySegment<byte>(PacketData, ReadPos, packetDataSize);
// 읽은 위치 조정
ReadPos += packetDataSize;
return completePacketData;
}
- ArraySegment : .NET에서 제공하는 배열의 일부분을 나타내는 구조체
NextFree
bool NextFree()
{
// 쓸 수 있는 크기 측정 : 버퍼 사이즈 - 마지막으로 쓴 위치
var enableWriteSize = BufferSize - WritePos;
// 쓸 수 있는 크기가 최대 패킷 사이즈보다 작으면
if (enableWriteSize < MaxPacketSize)
{
return false;
}
return true;
}
- 현재 쓸 수 있는 크기가 최대 패킷 사이즈보다 큰 지 작은지 측정해서 true false 반환
- 쓸 수 있는 크기가 크면 = 더 쓸 수 있다 / 작으면 = 더 못 쓴다
❓BufferRelocate