네트워크 통신에서 사용자 버퍼가 필요한 이유를 살펴보자.
✅ 비동기 I/O와 데이터 누락 방지
- 네트워크는 데이터를 순식간에 전송하거나 수신하지 못할 수 있다.
- OS에서 recv()나 WSARecv() 호출 시 받은 데이터의 양이 프로그램이 기대한 양보다 적을 수 있다.
- 이런 경우 사용자 버퍼에 누적하여 전체 패킷을 구성해야 한다.
예를 들어
- TCP 스트림으로 100바이트를 클라이언트에서 전송
- 서버에서 recv() 에서 60바이트만 수신
- 나머지 40바이트는 다음 호출 때 수신, 이후 사용자 버퍼가 누락된 데이터를 기억해줘야함
✅ 부분 송수신 대응 ( TCP의 특성 )
- TCP는 패킷 단위가 아니라 바이트 스트림
- 한 번의 recv()로 하나의 패킷이 온전히 들어온다는 보장이 없음
✅ 수신 / 송신 처리 분리
- 사용자 버퍼를 통해 앱 로직과 OS I/O 호출을 분리할 수 있다
- 수신 데이터를 사용자 버퍼에 모아두고, 패킷 단위로 처리하거나 송신 데이터를 사용자 버퍼에 모아두고, OS 전송이 가능할 때 전송하게 설계 가능
✅ 패킷 조립 / 파싱 편의
- 수신된 데이터를 사용자 버퍼에 저장하고, 패킷 헤더 확인, 패킷 길이 검사, 완전한 패킷인지 확인, 부족하면 더 받기 와 같은 과정이 가능하려면 임시 저장소가 필요
위와 같은 이유로 사용자 버퍼가 필요하다.
이번 채팅 서버에 사용할 사용자 버퍼는 원형큐버퍼로 일명 RingBuffer라 불린다.
✅ RingBuffer
메모리를 원형으로 사용하는 고정 크기 순환 버퍼다. 네트워크 통신, 스트림 처리 등에 사용되고 FIFO 구조를 가진다.
#pragma once
#include <iostream>
using namespace std;
#define BUFFER_DEFAULT_SIZE 100001
#define BLANK 1
#ifdef RINGBUFFER
#define RINGBUFFER_DLL __declspec(dllexport)
#else
#define RINGBUFFER_DLL __declspec(dllimport)
#endif
// 원형 큐
class RINGBUFFER_DLL RingBuffer
{
private:
char* _buffer;
int _front;
int _rear;
int _bufferMaxSize;
bool Init(int bufferSize);
public:
RingBuffer(void);
RingBuffer(int bufferSize);
~RingBuffer();
int GetBufferSize(void);
//현재 사용하고 있는 버퍼 크기 반환
int GetUseSize(void);
//남아 있는 공간 사이즈
int GetFreeSize(void);
// 한번에 enqueue 할 수 있는 사이즈
int GetDirectEnqueueSize(void);
// 한번에 Dequeue 할 수 있는 사이즈
int GetDirectDequeueSize(void);
// 데이터 넣기
int Enqueue(char* data, int size);
// 데이터 빼기
int Dequeue(char* dest, int size);
// 데이터가 있는지 확인
int Peek(char* dest, int size);
// rear 움직이기
int MoveRear(int size);
// front 움직이기
int MoveFront(int size);
// ringbuffer 초기화
void ClearBuffer(void);
// 비어잇는지 확인
bool IsEmpty(void);
// front 위치 반환
char* GetFrontBufferPtr(void);
// rear 위치 반환
char* GetRearBufferPtr(void);
// buffer 맨앞 반환
char* GetBufferPtr(void);
};
위처럼 RingBuffer를 구성했다. 내부적으로 buffer를 관리한다.
'ChattingServer' 카테고리의 다른 글
[ChattingServer] AcceptThreadProc (0) | 2025.06.01 |
---|---|
[ChattingServer] Session (0) | 2025.05.29 |
[ChattingServer] 직렬화 버퍼 (0) | 2025.05.29 |
[ChattingServer] 패킷 구조 (0) | 2025.05.29 |
[ChattingServer] 채팅 서버 시작 (0) | 2025.05.29 |