네트워크 통신에서 사용자 버퍼가 필요한 이유를 살펴보자.

✅ 비동기 I/O와 데이터 누락 방지

  • 네트워크는 데이터를 순식간에 전송하거나 수신하지 못할 수 있다.
  • OS에서 recv()나 WSARecv() 호출 시 받은 데이터의 양이 프로그램이 기대한 양보다 적을 수 있다.
  • 이런 경우 사용자 버퍼에 누적하여 전체 패킷을 구성해야 한다.

예를 들어

  1. TCP 스트림으로 100바이트를 클라이언트에서 전송
  2. 서버에서 recv() 에서 60바이트만 수신
  3. 나머지 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

+ Recent posts