반응형

C#과 유니티로 만드는 MMORPG 게임 개발 시리즈 210

Part 4-3-3. 네트워크 프로그래밍 : 소켓 프로그래밍 입문

네트워크 프로그래밍 이론 오늘은 소켓 프로그래밍에 대해서 알아보는 시간을 가져보도록 하자. 그렇지만 다짜고자 바로 코딩을 시작하면 어렵기 떄문에 프로그램의 어떻게 동작하는지 전체적인 흐름을 알아보자. 😋 손님 가게 가게에 방문하고 싶은 손님 입구 만들기, 문지기 고용 - 문지기 교육 입장 문의 영업 시작 소통 (직원) 안내 (소통) 손님은 본인이 가게에 방문하는 것이 아닌 대리자를 통해 가게를 방문한다. 핸드폰을 통해 식당 번호로 입장 문의를 하고, 가게는 문지기를 통해 손님의 요청을 받을지 말지 결정하고, 만약 받게 되다면 가게 내부로 안내하게 되며 서로 소통이 가능한 상태가 된다. 이러한 상황을 소켓 프로그래밍에 대입하면 아래와 같은 구조가 된다. 즉 클라이언트가 손님의 역할을 맡고, 가게가 서버의 ..

Part 4-3-2. 네트워크 프로그래밍 : 통신 모델(OSI 7 계층)

네트워크 프로그래밍 통신 모델에 대해서 알아보자. 컴퓨터 공학을 배웠다면 이는 OSI 7 계층에 해당하는 개념이다. 다시 예제를 살펴보자. 우리는 지난 시간에 택배 예제를 학습하며 같은 단지, 다른 단지 내에서 전송할 때에 어떻게 해야 하는지 학습했다. 그러나 사실 택배를 어떻게 보낼 지에 대한 방법이나, 무엇을 보낼지, 어덯게 보낼지에 대한 방법은 하나도 생각하지 않은 것이다. 따라서 택배를 보낸다면 아래와 같은 추가적인 정책이 필요하다. 이를 네트워크 단계로 다시 표현하자면 상품은 어플리케이션 단계와 같다. 이는 유저 인테페이스를 정의하는 것이다. 웹 통신을 사용하면 HTTP, 파일 다운로드를 한다면 FTP 등을 사용하는 것이다. 배송 정책은 트랜스포트 단계와 같다. 전송을 어떻게 확인하고 오류를 처..

Part 4-3-1. 네트워크 프로그래밍 : 네트워크 기초 이론

네트워크 프로그래밍 멀티쓰레드 프로그래밍이 모두 마치고 네트워크 프로그래밍으로 파트로 넘어왔다! 😎 사실 클라이언트 개발자는 네트워크 분야까지 알아야 할 필요성은 없지만 우리는 서버를 사용해야하기 때문에 네트워크까지 학습한다. 따라서 서버의 안전성 및 보안 등을 관리해야 하기 떄문에 네트워크가 어떤 구조로 어떻게 이루어져 있는지 알 필요가 있다. 고로 기초적인 네트워크 지식이 필요하다. 네트워크 패킷을 보내는 방식은 택배를 보내는 방식과 매우 유사하다. 우리가 택배를 보내려고 하는데, 받는 사람이 같은 아파트 단지 내에 있는 사람이라면 받는 사람의 집까지 찾아가서 택배를 놓고 오면 된다. 그러나 이 방법은 아파트 단지 내에 호수가 많아지면 문제가 생긴다. 같은 아파트 단지여도 여러 호수가 있어 받는 사람..

Part 4-2-15. 멀티쓰레드 프로그래밍 : TLS(Thread Local Storage)

멀티 쓰레드 TLS(Thread Local Storage) 쓰레드마다 고유하게 접근할 수 있는 전역 변수. TLS는 왜 필요할까? PPT와 예제를 통해 알아보잣! 🤠 우리는 락을 이용해 화장실처럼 동시 다발적으로 사용해야 하는 공간을 자물쇠를 이용해 사용하는 방법에 대해서 알아보았다. 여기까지만 보면 아름답지만, 현실은 녹록치 않다. 왜냐하면 주방에서 일어나는 일, 결제, 손님 테이블에서 일어나는 일 모두 각각의 직원이 대략적으로 현재 상황이 어떻게 이뤄지고 있는지 알아야 되기 때문이다. 즉 위의 이미지의 화살표처럼 일이 일사천리로 수월하게 처리되는 것이 아니라는 것이다. 그렇다면 락을 이용해 경합이 일어날 만한 곳에 락을 잡으면 되지 않을까? 생각할 수 있다. 하지만 이도 녹록치 않다. 왜냐하면 직원들..

Part 4-2-14. 멀티쓰레드 프로그래밍 : ReaderWriterLock 구현 연습

멀티 쓰레드 ReaderWriterLock을 구현해보자! 먼저 소스코드가 길어질 수 있으므로 ServerCore의 새로운 스크립트를 Lock.cs로 만들어주자. namespace ServerCore { class Lock { int _flag; } } 새로운 플래그를 위와 같이 설정하자. 플래그는 int형 변수를 사용하기 때문에 32비트를 가지게 된다. 우리는 32비트의 구조를 이용하여 Write의 영역과 Read의 영역을 구분할 것이다. 맨 앞의 1번 비트는 사용하지 않는다. 왜냐하면 해당 값을 사용하게 되면 음수의 값을 사용하기 때문이다. 따라서 우리는 2번 비트부터 16번 비트까지는 WriteThreadID의 영역을 이용해 쓰레드 아이디를 저장하고, 17번 비트부터 32번 비트까지는 ReadCoun..

Part 4-2-13. 멀티쓰레드 프로그래밍 : ReaderWriterLock

멀티 쓰레드 복습! 🤠 락을 구현하는 때에는 3가지 방법이 있다. 1. 근성, 2. 양보, 3. 갑질. ❗ 근성은 계속 빙글빙글 lock을 돌며 대기하는 것이고, 양보는 잠시 쉬었다가 다시 와서 획득 시도를 요청하는 것이다. 마지막으로 갑질은 직원을 시켜 알려달라 요구하는 것이다. 일전에 얘기했던 것과 같이 3가지 방법 중 뭐가 가장 좋고, 나쁘다 라고 말할 수 없으며 각각의 장점이 각각의 단점을 보완하는 형태이기 때문에 본인에게 필요한 방법을 사용하기로 하자. 그 동안 사용했던 Lock Lock 👉 내부적으로 Monotor 클래스를 이용해 편리하게 사용 가능한 락이다. (상호배제) static object key = new object(); static void Main(string[] args) { ..

Part 4-2-12. 멀티쓰레드 프로그래밍 : 이벤트(AutoResetEvent, ManualResetEvent), 뮤텍스

멀티 쓰레드 이벤트(AutoResetEvent) 오늘의 주제는 이벤트를 이용한 락 구현이다. 이전 시간에서 직원을 새로 고용해서 직원에게 부탁하는 방법이 이에 해당한다. 그렇지만 사실 해당 직원은 식당 직원이 아닌 커널 레벨에 있는 식당 관리자에 해당하는 것이다 😲.. 이런 식으로 커널 레벨로 옮겨서 실행을 할 때에는 어마어마하게 느리다는 단점이 있다. 대신 본인 입장에서는 시간을 낭비하는 것이 아니므로 행동을 이어가는 장점이 있다. C#에서는 이벤트를 구현할 때에는 두 가지 방법이 있다. 1. Auto Reset Event 이는 톨케이트를 생각하면 된다. 톨게이트를 보면 차가 한대한대씩 지나가고, 지나갈 때마다 톨게이트가 닫혀 대기해야 하는 상황이 발생하는데 이것이 바로 Auto Reset Event의..

Part 4-2-11. 멀티쓰레드 프로그래밍 : 문맥 교환(Context Switching)

멀티 쓰레드 문맥 교환 (=컨텍스트 스위칭(Context Switching)) 우리는 이전 시간에 아래와 같은 코드에서 while문을 이용해 반복적으로 실행되는 것을 스핀락이라고 학습하였다. 그렇지만 문맥 교환 방법(PPT 예시 - 랜덤 메타 방식)으로 이를 구현하려고 하면 어떻게 해야할까? 방법은 간단하다. 아래 소스코드에서 일정 시간을 쉬다가 오면 이것이 문맥 교환 방법이 되는 것이다. public void Acquire() { while (true) { int expected = 0; int desired = 1; if (Interlocked.CompareExchange(ref _locked, desired, expected) == expected) break; } } 쉬는 방법에는 총 세 가지의 ..

Part 4-2-10. 멀티쓰레드 프로그래밍 : SpinLock

멀티 쓰레드 SpinLock 락 구현 이론을 바탕으로 스핀 락을 실제로 구현해보자. 또한 스핀 락의 개념은 매우 중요해서 면접에서 멀티쓰레드 프로그래밍을 경험했다고 하면 0순위로 물어본다고 하니, 이번 기회에 확실하게 알고 넘어가자. 😎 using System; using System.Threading; using System.Threading.Tasks; namespace CSharp { class SpinLock { // 상태 // true = 사용하는 중(잠금) // false = 사용하지 않는 중(미잠금) volatile bool _locked = false; // 획득 public void Acquire() { while (_locked) { // 기다리는 중... 😩 } _locked = tr..

Part 4-2-9. 멀티쓰레드 프로그래밍 : Lock 구현 이론

멀티 쓰레드 Lock 구현 이론 오늘의 주제는 락 구현 연습이다. 멀티쓰레드 프로그래밍의 락의 비중은 6-70%를 차지할 정도로 매우 중요하다. 따라서 락의 동작방식을 이해하는 것은 매우 중요하다. 물론 언어와 프레임워크에 따라 조금씩 다르겠지만, 근본적인 구조와 동작 방법은 유사할 것이다. 오늘도 비유를 이용하여 Lock 구현 이론에 대해서 알아보자. 이전 시간에서 락의 구현은 화장실을 갔다오는 것과 유사하다고 했다. 예를 들어보자. 우리는 화장실에 갔는데 누군가 화장실 안에서 사용하고 있어 문을 잠군 상태이다. 따라서 우리는 안에 사람이 나오기를 기다리고 있는 상황이라고 가정해보자. 즉. 화장실이 급해서 왔는데 문이 잠겨있는 상태인 것이다. 그렇다면 우리는 이 때 어떻게 행동할까? 1. 무작정 기다리..

Part 4-2-8. 멀티쓰레드 프로그래밍 : 데드락

멀티 쓰레드 데드락 데드락의 발생 조건은 이전 시간에 알아본 상호배제 말고도 다양한 상황에서 다양한 조건으로 일어난다. 데드락 발생 조건의 다른 예시를 알아보자. 파란색이 화장실이라고 가정하고, 화장실에는 자물쇠가 2개가 잠겨 있는데, 이 때 직원 A, B가 화장실을 이용하기 위해 서로 경쟁을 한다고 가정해보자. 직원 A는 위의 자물쇠를 획득하고, 직원 B는 아래의 자물쇠를 획득했다. 하지만 자물쇠는 두 개를 동시에 가지고만 있어야만 열 수 있는데, 상황이 이렇게 되니 직원 A는 위 자물쇠를 획득한 상태에서 아래 자물쇠를 직원 B에게 달라고 요청을 하고, 직원 B는 아래 자물쇠를 획득한 상태에서 위 자물쇠를 직원 B에게 달라고 요청을 하는 상태가 된다. 즉 아래 이미지와 같이 되는 것이다. 따라서 이런 ..

Part 4-2-7. 멀티쓰레드 프로그래밍 : Lock 기초

멀티 쓰레드 Lock (OS에서는 크리티컬 섹션(CriticalSection), C++에서는 std::mutex 라고 불린다.) Interlocked 계열 메서드는 성능도 빠르고 좋긴 하지만, 단점이 존재한다. 바로 정수만 사용할 수 있는 것이다. 우리가 나중에 멀티 쓰레드를 이용해 프로그램을 짤 때에는 단순히 number++ 만을 하지는 않을 것이다. 따라서 특정 신호를 주어서 사용자가 정한 블록 안의 내용은 하나의 쓰레드만 실행하도록 제어할 수 있는 도구가 필요할 것이다. 먼저 소스코드 내 가상의 선을 긋는다고 생각하자. 이 영역은 아무도 접근할 수 없으며, 내가 먼저 점유할 경우 다른 쓰레드는 얼씬도 하지 못한다. 라고 생각하자. class Program { static int number = 0;..

Part 4-2-6. 멀티쓰레드 프로그래밍 : interlocked

멀티 쓰레드 지난 시간까지 하드웨어 최적화로 인한 문제를 살펴보았다. 그러나 사실 이는 생각보다 크게 신경쓰지 않아도 된다. 왜냐하면 락, 아토믹 같은 것들을 사용하는 솔루션이 있기 때문이다. 오늘은 공유 변수 접근에 대한 문제점에 대해서 또 다른 실험을 할 예정이다. 😀 소스코드는 아래와 같다. using System; using System.Threading; namespace ServerCore { class Program { static int number = 0; static void Thread_1() { for (int i = 0; i < 10000; i++) number++; } static void Thread_2() { for (int i = 0; i < 10000; i++) numbe..

Part 4-2-5. 멀티쓰레드 프로그래밍 : 메모리 배리어

멀티 쓰레드 이전 시간에서는 컴파일러가 소스 코드를 최적화하여 우리가 원하던 방향으로 정상적으로 작동하지 않는 문제가 발생하였다. 그러나 사실 컴파일러 뿐만 아니라 소스 코드를 최적화 하는 또 다른 존재가 있었으니 바로 하드웨어(HW)이다. 따라서 오늘 실습할 것은 하드웨어가 진행하는 최적화 메모리 배리어에 대해서 학습해보겠다. 🤠 코드는 아래와 같다. class Program { static int x = 0; static int y = 0; static int r1 = 0; static int r2 = 0; static void Thread_1() { y = 1; // Store y r1 = x; // Load x } static void Thread_2() { x = 1; // Store x r2 ..

Part 4-2-4. 멀티쓰레드 프로그래밍 : 캐시 이론

멀티 쓰레드 캐시 지난번과 동일하게 패밀리 레스토랑을 예로 들어 이해해보자 👍 지난시간 우리는 패밀리 레스토랑인 아웃백을 개업하고 직원(로봇)을 채용해 영혼을 통해 로봇을 움직였다. 그러나 레스토랑이 궤도에 올라서 손님도 많아지고 돈도 많아졌는데 손님이 몰리다보니 일처리를 어떻게 해야할지 고민이 생긴것이다. 오른쪽을 보면 주문 현황을 볼 수 있다. 테이블을 돌아다니며 주문을 받는 직원이 있는데 주문을 받으면 주방으로 전달을 해야 주문이 들어간다. 이 식당에는 주문 현황 기계가 있는데 이 기계에 주문을 기입하면 주방에서 주문서가 나와 음식 조리가 시작된다. 그런데 하나의 문제가 있다. 주문 현황판이 멀리 있다는 것이다. 그렇다면 직원은 이를 어떻게 해결하는 것이 가장 좋을까? 다양한 해결 방법이 있다. 1..

Part 4-2-3. 멀티쓰레드 프로그래밍 : 컴파일러 최적화

멀티 쓰레드 컴파일러 최적화 using System; using System.Threading; namespace ServerCore { class Program { static bool _stop = false; static void ThreadMain() { Console.WriteLine("쓰레드 시작!"); while (_stop == false) { // 누군가 stop 신호를 해주기를 기다린다! } Console.WriteLine("쓰레드 종료!"); } static void Main(string[] args) { // 메인에서 쓰레드를 생성하고 실행한다 Task t = new Task(ThreadMain); t.Start(); // 멈춘다 _stop = true; Console.WriteLi..

Part 4-2-2. 멀티쓰레드 프로그래밍 : 쓰레드 생성

멀티 쓰레드 정직원 쓰레드 생성 using System.Threading; class Program { static void MainThread(object state) { Console.WriteLine("Hello, Thread!"); } // 메인 직원 static void Main(string[] args) { // 직원을 한명 더 고용하고, 일을 시킨다. Thread t = new Thread(MainThread); t.Start(); Console.WriteLine("Hello, World!"); } } 쓰레드를 생성하고 초기화 하는 것은 어렵지 않다. Thread t = new Thread()로 새로운 쓰레드를 만들어준다. 새로운 메서드를 MainThread라고 만들어주고 생성한 쓰레드 안에..

Part 4-2-1. 멀티쓰레드 프로그래밍 : 멀티쓰레드 개론

멀티 쓰레드 서버는 멀티쓰레드를 활용한다. 여태까지 자료구조와 알고리즘은 기초 지식이 없어도 충분히 이해하고 활용할 수 있지만, 멀티쓰레드부터는 원할한 이해를 위해선 컴퓨터 구조 원리와 운영체제의 기본 지식이 필요하다. 따라서 오늘은 당장 코드로 이런, 저런 작업을 하는 것이 아닌 멀티쓰레드 개론에 대해서 얘기한다. 서버를 운영하는 것은 식당을 운영하는 것과 같다. 우리가 크게 한식, 일식, 그리고 이보다 규모가 조금 큰 패밀리 레스토랑 총 3가지의 식당을 운영한다고 가정해보자. 로봇 직원은 혼자서 아무것도 하지 못하는 상황이며, 식당 관리자인 우리는 영혼을 각 식당의 로봇에게 부여한다고 한다. 이 때 영혼도 1개라고 가정한다. 그렇다면 영혼이 1개인데 각 식당의 로봇을 어떻게 관리하고 일을 시킬수 있을..

Part 4-1-1. 서버 OT 및 환경 설정

게임 서버 개론 서버란? 서버 👉 다른 컴퓨터에서 연결이 가능하도록 대기 상태로 상시 실행 중인 프로그램 영업 중인 식당과 유사하다. 손님이 올 수 있도록 식당 열고 대기하다가 손님 오면 서비스 제공 ✈ 서버의 종류 1️⃣ Web Server 1️⃣ Web Server ex) HTTP 질의/응답 형태 1. 정보 요청/갱신이 드물다. 2. 한번만 질의 응담 받고 떠남 단순히 한번만 교류 간단한 요청과 그에 대한 응답을 할 때 많이 사용한다. 예를 들어 로그인, 랭킹 시스템 불러오기 같은 단발성으로 불러오고 말 것들은 웹서버를 사용하는 것이 좋을 것 같다. 3. 실시간 상호 교류가 필요하지 않다. 4. 식당에서 직원이 손님에게 먼저 접근하는 일이 없다. 즉, 서버가 먼저 클라에게 접근하는 일이 없다. 테이크..

반응형