1차원 배열을 연속적으로 이어져있는 것처럼 사용하는 방식
데이터를 수신하면 한 번에 모든 데이터를 읽을 수 없고 계속해서 데이터가 수신될 때,
데이터 순서가 보장되지 않는 TCP의 단점을 보완하기 위한 방법.
readPos와 writePos가 같으면 현재 데이터가 없는 것이다.
=> 모든 인덱스를 초기 위치로 이동.
데이터를 읽는 도중 버퍼의 공간이 부족할 때
=> 데이터와 인덱스를 배열의 초기 위치 기준으로 복사한다.
1. 버퍼 생성
[][][][][] -> [rw][][][][]
2. 2byte 데이터 수신
[r][][w][][]
3. 2byte 데이터 수신
[r][][][][w]
4. 수신 처리 완료 => 인덱스 이동
[][][][][rw] -> [rw][][][][]
---------------------------------
1. 버퍼 생성
[][][][][] -> [rw][][][][]
2. 4byte 데이터 수신
[r][][][][w]
3. 3byte만 수신 완료 => 데이터 복사 및 인덱스 이동
[][][r][][w] -> [r][][w][][]
// 1. 버퍼 세팅
int32 BUFFER_SIZE = 0x10000;
int32 BUFFER_COUNT = 10;
int32 _capacity = 0;
int32 _bufferSize = 0;
int32 _readPos = 0;
int32 _writePos = 0;
Vector<BYTE> _recvBuffer;
_bufferSize = BUFFER_SIZE;
_capacity = _bufferSize * BUFFER_COUNT;
_recvBuffer.resize(_capacity);
// 2. recv
WSABUF wsaBuf;
wsaBuf.buf = reinterpret_cast<char*>(_recvBuffer[_writePos]);
wsaBuf.len = _capacity - _writePos;
DWORD numOfBytes = 0;
DWORD flags = 0;
WSARecv(SOCKET, &wsaBuf, 1, OUT & numOfBytes, OUT & flags, OVERLAPPED, nullptr);
// 3. index 확인
int32 dataSize = _writePos - _readPos;
int32 freeSize = _capacity - _writePos;
if (numOfBytes <= freeSize)
_writePos += numOfBytes;
if (numOfBytes <= dataSize)
_readPos += numOfBytes;
// 4. index 정리
if (dataSize == 0)
{
_readPos = _writePos = 0;
}
else
{
// 여유 공간이 버퍼 1개 크기 미만
if (freeSize < _bufferSize)
{
memcpy(&_recvBuffer[0], &_recvBuffer[_readPos], dataSize);
_readPos = 0;
_writePos = dataSize;
}
}
버퍼 공간이 부족해서 데이터와 인덱스를 배열의 초기위치로 복사하는 경우보다,
readPos와 writePos가 같아 인덱스만 배열의 초기 위치로 이동시키는 경우의 비용이 상대적으로 낮다.
따라서 버퍼의 크기를 상대적으로 크게 설정하면 유리하다.
코드)
https://github.com/Juzdalua/Study-Cpp-Server/blob/master/ServerCore/RecvBuffer.h
Study-Cpp-Server/ServerCore/RecvBuffer.h at master · Juzdalua/Study-Cpp-Server
Study C++ IOCP. Contribute to Juzdalua/Study-Cpp-Server development by creating an account on GitHub.
github.com
'Server > C++' 카테고리의 다른 글
문자집합과 인코딩 (0) | 2024.08.19 |
---|---|
WSASend에서 Scatter-Gather 기법 사용하기 (0) | 2024.08.16 |
class 자신을 참조하는 shared_ptr (0) | 2024.08.13 |
IOCP Completion Port 모델 (0) | 2024.08.13 |
Overlapped 모델 (0) | 2024.08.13 |