분류 전체보기 39

4. 소켓 옵션

이번에는 간단하게 소켓 옵션을 설정하는 방법에 대해 알아보자. 소켓을 만들 때 기본적으로 커널에서 샌드, 리시브 버퍼(송수신 버퍼)가 만들어진다. 이 버퍼도 크기를 변경하는 등 프로그래머가 옵션을 설정할 수 있다. ::setsockopt();::getsockopt();이 두 함수를 통해 옵션을 설정하고 가져올 수 있다. 자세한 내용은 마이크로소프트 공식문서에 잘 나와있다. https://learn.microsoft.com/ko-kr/windows/win32/api/winsock2/nf-winsock2-setsockopt setsockopt 함수(winsock2.h) - Win32 appssetsockopt 함수(winsock2.h)는 모든 형식의 소켓과 연결된 소켓 옵션의 현재 값을 모든 상태로 설정합니..

서버/네트워크 2024.09.01

3. UDP 서버

TCP 서버를 알아보았으니 이제 코드를 수정해보면서 UDP 서버에 대해 알아보자. 일반적으로 TCP는 안정성이 높고 패킷의 도착순서를 보장하는 반면 UDP는 그렇지 못하지만 속도가 빠르고 바운더리(패킷과 패킷 사이의 경계)가 존재한다는 특징이 있다. 두 가지 전부 장단점이 있으므로 필요에 따라 적절한 프로토콜을 사용하면 된다. 채팅이나 아이템 거래 등과 같이 데이터가 유실되면 문제가 생기거나 패킷 수신의 순서가 중요한 경우 TCP를 사용하면 될 것이고, FPS와 같은 실시간 통신 게임이나 스트리밍 서비스와 같이 빠른 반응이 필요할 경우 UDP를 사용하면 될 것이다. DummyClient.cpp#include "pch.h"#include #include #include #include #pragma com..

서버/네트워크 2024.08.30

2. TCP 서버

간단한 서버의 구조를 만들어보았으니 이제 데이터를 보내고 받는 작업을 해보자. Dummyclient.cpp#include "pch.h"#include #include #include #include #pragma comment(lib, "ws2_32.lib")int main(){ // 윈속 라이브러리 초기화 (ws2_32 라이브러리 초기화) // 관련 정보가 wsaData에 채워짐 WSAData wsaData; if (::WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) return 0; // af : Address Family (AF_INET = IPv4, AF_INET6 = IPv6) // type : TCP(SOCK_STREAM) vs UDP(SOCK_DGRAM) // ..

서버/네트워크 2024.08.29

1. 소켓 프로그래밍

드디어 뭔가 통신같아 보이는 파트로 넘어왔다. 바로 코드부터 살펴보자. DummyClient.cpp#include "pch.h"#include #include #include #include #pragma comment(lib, "ws2_32.lib")int main(){ // 윈속 라이브러리 초기화 (ws2_32 라이브러리 초기화) // 관련 정보가 wsaData에 채워짐 WSAData wsaData; if (::WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) return 0; // af : Address Family (AF_INET = IPv4, AF_INET6 = IPv6) // type : TCP(SOCK_STREAM) vs UDP(SOCK_DGRAM) // prot..

서버/네트워크 2024.08.29

8. Object Pool

저번의 메모리 풀에는 뭔가가 아쉬운 부분이 있다. 직접 구현한 메모리 풀에서는 사이즈가 비슷한 객체들을 하나의 풀에 넣어서 관리를 했다. 사이즈가 조금이라도 다른 객체들이 같은 풀에 있다보니 해당 풀에서 메모리 오염이 발생할 가능성이 있다. 만약 어떤 한 클래스에서 오류가 났다면 그 클래스의 코드만 살펴보면 되지만 이런 경우 어디서 오류가 발생했는지 탐지하기도 굉장히 힘들다. 그래서 이번에 알아볼 것이 오브젝트 풀이다. 생각해보면 알겠지만 메모리 풀이 오브젝트 풀의 상위 개념이다. 오브젝트 풀을 포함하고 있다는 것이다.  ObjectPool.h#pragma once#include "Types.h"#include "MemoryPool.h"templateclass ObjectPool{public: templ..

7. Memory Pool #2

ABA Problem이라는 것이 있다. CAS(Compare And Swap)에서 오류를 감지하지 못하는 것인데 쉽게 예시를 설명하자면 이렇다. 10 -> 20 -> 30 과 같이 리스트로 연결된 데이터가 있다고 하자.A 스레드가 CAS를 이용하여 제일 앞의 10을 40으로 바꾼다고 해보자. 그렇다면 10 -> 20 -> 30이라는 리스트를 저장 후 '만약 제일 앞의 데이터가 10이면 40으로 바꾸어라' 이렇게 작동할 것이다. 하지만 멀티스레드 환경에서 CAS를 실행하기 전 다른 여러 스레드에서 pop 2번이 일어나 10과 20의 메모리가 반환 되고, push 1번 일어나서 10이라는 메모리를 재활용해 다시 할당 받았다고 가정하여 10 -> 30이 되었다고 생각해보자. 그렇게 되면 제일 앞의 데이터는 1..

6. Memory Pool #1

지금까지는 필요할 때 메모리를 할당하고 사용이 끝나면 해제하였다. 하지만 매번 할당하고 해제하는 것이 비효율적이라고 느낄 수도 있고 메모리 단편화에 대한 문제도 있다.(요즘은 할당기가 잘 되어 있어 단편화에 대한 문제는 크게 신경쓸 필요는 없다고 한다.) 풀이라는 것은 직역하면 수영장 뭐 이런 뜻인데 수영장에 물을 담아놓는 것처럼 메모리를 담아놓았다가 필요할 때 꺼내 쓰는 것이다. 메모리를 사용하고 해제하는 것이 아니라 그냥 풀에 스윽 던져놓는 것이다. 그래서 매번 할당하고 해제할 필요성이 없다. 객체단위로 풀링을 하는 오브젝트 풀링이라는 것을 들어보았을 것이다. 하지만 우리가 동적할당할 것들은 객체뿐만 아니라 벡터, 맵 등 다양한 자료구조에 대해서도 동적할당을 해야한다. 이런 상황(크기가 일정하지 않음..

5. STL Allocator

일반적인 클래스나 자료형은 지금까지 했던 Allocator를 이용하여 메모리를 할당하고 해제할 수 있었다. 메모리 오염 또한 방지할 수 있었는데 벡터나 맵 등 다른 자료구조에 대해서는 아직 내부적으로 new, delete를 사용하고 있을 것이다. 이번에는 이를 한 번 수정해보자.벡터 클래스의 선언부를 보면 타입과 Allocator를 지정할 수 있다.vector> v;이런식으로 사용할 수 있다는 뜻이다!!! 하지만 매번 위와 같이 지정할 수는 없으므로 헤더파일을 하나 만들어보자. Container.h#pragma once#include "Types.h"#include "Allocator.h"#include #include #include #include #include #include #include #i..

4. Stomp Allocator

메모리가 이미 해제되었는데 사용하거나 사용할 수 있는 범위를 넘어서 사용하는 등 유효하지 않은 메모리 영역에 접근하는 것을 메모리 오염이라고 한다. 메모리 오염의 경우 크래시가 나지 않을 때도 있어 프로그램에 치명적일 수 있다. 예를 들어 허용된 범위를 넘어 메모리에 접근을 했는데 이미 다른 객체가 사용중인 메모리라던가 아니면 게임같은 경우 골드와 같이 유료재화를 담당하는 메모리라고 생각해보자. 이러한 상황을 예방하기 위한 것이 바로 Stomp Allocator이다. Allocator.h//-------------------// StompAllocator//-------------------class StompAllocator{ enum { PAGE_SIZE = 0x1000 }; // 4kbpublic..

3. Allocator

메모리를 관리하기 위해서 일반적으로 new와 delete를 사용한다. 하지만 메모리를 사용하고 반납하는 과정에서 조각난 공간들이 생기게 되고 그렇게 되면 분명 빈 메모리가 있음에도 제대로 사용할 수 없는 상황이 생기게 된다. 이런 상황을 메모리 단편화라고 한다. 이러한 상황을 예방할 수 있는 메모리풀을 구현하기 위한 초석으로 간단하게 new와 delete를 새롭게 만들어 보자. Allocator.h#pragma once//------------------// BaseAllocator//------------------class BaseAllocator{public: static void* Alloc(int32 size); static void Release(void* ptr);};Allocator.c..