[Book] κ²Œμž„ μ„œλ²„ ν”„λ‘œκ·Έλž˜λ° κ΅κ³Όμ„œ - 6μž₯ κ²Œμž„ λ„€νŠΈμ›Œν¬ μ—”μ§„ ν”„λΌμš°λ“œλ„·

2022. 2. 26. 15:01Β·πŸ“ Book/✏ Game Server

6μž₯ κ²Œμž„ λ„€νŠΈμ›Œν¬ μ—”μ§„ ν”„λΌμš°λ“œλ„·

 

1. κ²Œμž„ μ„œλ²„, λ„€νŠΈμ›Œν¬ μ—”μ§„

κ²Œμž„ μ„œλ²„μ™€ λ©€ν‹°ν”Œλ ˆμ΄μ–΄ 처리λ₯Ό κ°œλ°œν•  λ•Œ λ„€νŠΈμ›Œν‚Ή 처리λ₯Ό μœ„ν•΄ 보톡 μ†ŒμΌ“ APIλ₯Ό μ΄μš©ν•œλ‹€. κ·ΈλŸ¬λ‚˜ μ†ŒμΌ“ API만 μ΄μš©ν•˜λ©΄ λ‹€μŒκ³Ό 같은 λ²ˆκ±°λ‘œμ›€μ΄ λ°œμƒν•  수 μžˆλ‹€.

  • μš΄μ˜μ²΄μ œλ§ˆλ‹€ μ†ŒμΌ“ APIλ₯Ό μ‚¬μš©ν•˜λŠ” 방식에 차이가 μžˆλ‹€.
  • μ†ŒμΌ“ APIμ—μ„œ μ œκ³΅ν•˜μ§€ μ•ŠλŠ” κΈ°λŠ₯은 직접 λ§Œλ“€μ–΄μ•Ό ν•œλ‹€.

 

κ·Έλž˜μ„œ μ΄λŸ¬ν•œ 문제λ₯Ό κ°œμ„ ν•˜κΈ° μœ„ν•΄ λ„€νŠΈμ›Œν¬ 엔진을 μ‚¬μš©ν•˜κΈ°λ„ ν•œλ‹€.

 

2. 개발 ν™˜κ²½κ³Ό κΈ°λ³Έ λͺ¨λ“ˆ

λ„€νŠΈμ›Œν¬ μ—”μ§„ 쀑 ν•˜λ‚˜μΈ ν”„λΌμš°λ“œλ„·μ€...

  • μƒμ—…μš© μ†Œν”„νŠΈμ›¨μ–΄λ‘œ κ°œμΈμ΄λ‚˜ νŠΉμ • 쑰건의 인디 κ°œλ°œμ‚¬μ—μ„œλŠ” 무료둜 μ‚¬μš©ν•  수 μžˆλ‹€.
  • ν΄λΌμ΄μ–ΈνŠΈ-μ„œλ²„ κ°„ λ„€νŠΈμ›Œν‚Ήκ³Ό ν΄λΌμ΄μ–ΈνŠΈ κ°„ 직접 λ„€νŠΈμ›Œν‚Ήμ„ λ‹¨μˆœν•˜κ²Œ μ‚¬μš©ν•  수 있게 ν•˜λ©° λ„€νŠΈμ›Œν¬ μ•”ν˜Έν™”, μ•”μΆ•, 흐름 μ œμ–΄ λ“± κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€.
  • 개발 μ–Έμ–΄λŠ” C++, C#을 μ§€μ›ν•œλ‹€.
  • μ„œλ²„ λͺ¨λ“ˆμ€ μœˆλ„ μ„œλ²„μ™€ λ¦¬λˆ…μŠ€λ₯Ό μ§€μ›ν•˜κ³  ν΄λΌμ΄μ–ΈνŠΈλŠ” μœˆλ„, λ¦¬λˆ…μŠ€, iOS, μ•ˆλ“œλ‘œμ΄λ“œ, ν”Œλ ˆμ΄μŠ€ν…Œμ΄μ…˜ 4λ₯Ό μ§€μ›ν•œλ‹€.

 

3. κ²Œμž„ ν΄λΌμ΄μ–ΈνŠΈ-μ„œλ²„ 톡신

λ„€νŠΈμ›Œν¬ λͺ¨λ“ˆμ€ 크게 클래슀 2개둜 λ‚˜λ‰œλ‹€.

  • NetServer 클래슀: κ²Œμž„ μ„œλ²„μ˜ 메인 λͺ¨λ“ˆλ‘œ ν΄λΌμ΄μ–ΈνŠΈμ˜ 연결을 λ°›μœΌλ©° λ©”μ‹œμ§€λ₯Ό μ£Όκ³ λ°›λŠ” 역할을 ν•œλ‹€. 또 각 ν΄λΌμ΄μ–ΈνŠΈμ˜ λ„€νŠΈμ›Œν¬ 상황 등을 μ—΄λžŒν•  수 μžˆλ‹€.
  • NetClient 클래슀: κ²Œμž„ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ λ„€νŠΈμ›Œν¬ λͺ¨λ“ˆλ‘œ μ„œλ²„와 연결을 맺은 ν›„ λ©”μ‹œμ§€λ₯Ό 주고받을 수 μžˆλ‹€. 또 λ‹€λ₯Έ ν΄λΌμ΄μ–ΈνŠΈμ™€ P2P 톡신도 κ°€λŠ₯ν•˜λ‹€.

 

ν΄λΌμ΄μ–ΈνŠΈ-μ„œλ²„ 접속 κ³Όμ •

 

NetServer μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³  ν΄λΌμ΄μ–ΈνŠΈ 접속을 λ°›μœΌλ €λ©΄, λ‹€μŒ μž‘μ—…μ΄ ν•„μš”ν•˜λ‹€.

  • CNetServer.Create()둜 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€.
  • CNetServer.Start()둜 ν΄λΌμ΄μ–ΈνŠΈ 접속을 λ°›λŠ”λ‹€. μ΄λ•Œ λ§€κ°œλ³€μˆ˜λ‘œ λ¦¬μŠ€λ‹ 포트 λ²ˆν˜Έμ™€ ν”„λ‘œν† μ½œ 버전을 보낸닀.
    • ν”„λ‘œν† μ½œ 버전은 μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈκ°€ λͺ¨λ‘ λ§žμΆ”μ–΄μ•Ό ν•œλ‹€.
CNetServer* s = CNetServer::Create();
param.m_tcpPorts.Add(44444);
param.m_udpPorts.Add(44444);
param.m_protocolVersion = Guid(
{ 0x5dca93f4, 0x8133, 0x44a0,{ 0xb5, 0x7b,
0x75, 0x7d, 0x9c, 0x78, 0xd5, 0x2e } });
 
s->Start(param);

 

ν΄λΌμ΄μ–ΈνŠΈλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³  μ„œλ²„μ— μ ‘μ†ν•˜λ €λ©΄, λ‹€μŒ μž‘μ—…μ΄ ν•„μš”ν•˜λ‹€.

  • CNetClient.Create()둜 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€.
  • CNetClient.Connect()둜 μ„œλ²„μ— μ ‘μ†ν•œλ‹€. μ΄λ•Œ λ§€κ°œλ³€μˆ˜λ‘œ μ„œλ²„ μ£Όμ†Œμ™€ 포트 κ°’, ν”„λ‘œν† μ½œ 버전을 보낸닀.
CNetClient* c = CNetClient::Create();
param.m_serverAddr = _PNT("my.game.com");
param.m_serverPort = 44444;
param.m_protocolVersion = Guid(...);

c->Connect(param);

 

μ„œλ²„μ— ν΄λΌμ΄μ–ΈνŠΈ 접속이 λ“€μ–΄μ˜€λ©΄, μ„œλ²„ μŠ€λ ˆλ“œ ν’€μ—μ„œ OnClientJoin() 이벀트 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€. OnClientJoin()은 ν΄λΌμ΄μ–ΈνŠΈ 접속이 λ“€μ–΄μ™”μŒμ„ μ•Œλ¦¬λŠ” 이벀트둜 ν•¨μˆ˜ 콜백 ν˜•νƒœμ΄λ‹€. 즉, 이벀트 ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜λ €λ©΄, κ°œλ°œμžλŠ” 이 이벀트λ₯Ό μ²˜λ¦¬ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄μ•Ό ν•˜κ³  ν”„λΌμš°λ“œλ„·μ€ κ·Έ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•΄ μ€€λ‹€.

s->OnClientJoin = [](CNetClientInfo* info) {
    // infoμ—λŠ” μƒˆ ν΄λΌμ΄μ–ΈνŠΈ 정보가 μžˆλ‹€.
    ...
};

 

μ„œλ²„ 접속이 μ™„λ£Œλ˜λ©΄, ν΄λΌμ΄μ–ΈνŠΈμ—μ„œλŠ” OnJoinServerComplete() 이벀트 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.

c->OnJoinServerComplete = [](ErrorInfo* result) {
    if (result->m_errorType = = ErrorType_Ok) {
        ... // 성곡 처리
    }
    else {
        print(result->ToString());
        ... // μ‹€νŒ¨ 처리
    }
};

 

일반적인 κ²Œμž„ ν΄λΌμ΄μ–ΈνŠΈλŠ” 메인 루프λ₯Ό κ°€μ§„λ‹€. 메인 λ£¨ν”„μ—μ„œλŠ” κ²Œμž„ 둜직 μ²˜λ¦¬μ™€ λ Œλ”λ§μ„ ν•˜λŠ”λ°, μ„œλ²„λ‚˜ λ‹€λ₯Έ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ 온 λ©”μ‹œμ§€λ₯Ό μ²˜λ¦¬ν•˜κ±°λ‚˜ 이벀트 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœλ°›λŠ” 것도 이 메인 루프 μ–΄λ”˜κ°€μ—μ„œ ν•  것이닀. FrameMove() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄, μ§€κΈˆκΉŒμ§€ λˆ„μ λœ μ΄λ²€νŠΈλ‚˜ μˆ˜μ‹ λœ λ©”μ‹œμ§€μ— λŒ€ν•œ 이벀트 콜백이 μΌμ–΄λ‚œλ‹€.

c->FrameMove();

 

λ‹€μŒμœΌλ‘œ ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ κ°„ μ—°κ²° ν•΄μ œμ΄λ‹€.

 

ν΄λΌμ΄μ–ΈνŠΈ-μ„œλ²„ μ—°κ²° ν•΄μ œ

 

ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ Disconnect() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ±°λ‚˜ μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈ 연결이 쀑간에 끊겨 OnLeaceServer() 이벀트 ν•¨μˆ˜κ°€ 호좜되면, μ„œλ²„μ—μ„œλ„ OnClientLeave() 이벀트 ν•¨μˆ˜κ°€ ν˜ΈμΆœλœλ‹€.

c->OnLeaveServer = [](ErrorInfo* reason) {
    // reasonμ—λŠ” μ™œ λŠμ–΄μ‘ŒλŠ”μ§€κ°€ 담겨 μžˆλ‹€.
    ...
};
s->OnClientLeave = [](CNetClientInfo* client,
    ErrorInfo* reason,
    const ByteArray& comment) {
    // 여기에 이벀트 처리 μ½”λ“œλ₯Ό μΆ”κ°€ν•œλ‹€.
};

 

4. λ©”μ‹œμ§€ μ£Όκ³ λ°›κΈ°

ν”„λΌμš°λ“œλ„·μ—μ„œ λ©”μ‹œμ§€λ₯Ό μ£Όκ³ λ°›λŠ” 방법은 크게 '전톡적인 λ°©λ²•μœΌλ‘œ λ°”μ΄λ„ˆλ¦¬ 데이터 μ£Όκ³ λ°›κΈ°'와 'λ‹€λ₯Έ 컴퓨터에 μžˆλŠ” ν•¨μˆ˜λ₯Ό μ›κ²©μœΌλ‘œ ν˜ΈμΆœν•˜κΈ°'κ°€ μžˆλ‹€.

 

전톡적인 λ°©λ²•μœΌλ‘œ λ°”μ΄λ„ˆλ¦¬ 데이터 μ£Όκ³ λ°›κΈ°λŠ” NetClient와 NetServer λ‚΄ SendUserMessage() ν•¨μˆ˜λ‘œ μƒλŒ€λ°©μ—κ²Œ λ©”μ‹œμ§€λ₯Ό μ „μ†‘ν•˜λŠ” 방법이닀. μ΄λ•Œ λ§€κ°œλ³€μˆ˜λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

  • λˆ„κ΅¬(HostID λ˜λŠ” HostID array): λ©”μ‹œμ§€λ₯Ό λ³΄λ‚΄κ³ μž ν•˜λŠ” λŒ€μƒ
  • μ–΄λ–»κ²Œ(reliable, unreliable λ“±): μ–΄λ–€ λ°©λ²•μœΌλ‘œ μƒλŒ€λ°©μ—κ²Œ λ©”μ‹œμ§€λ₯Ό 전솑할지
  • 무엇을(byte array): λ©”μ‹œμ§€
unsigned char data[100];
 
c->SendUserMessage(HostID_Server,
    RmiContext::ReliableSend, data, 100);
s->SendUserMessage(ClientHostID,
    RmiContext::UnreliableSend, data, 50);
 
HostID sendTo[10];
s->SendUserMessage(sendTo, 10,
    RmiContext::UnreliableSend, data, 30);

 

λ©”μ‹œμ§€λ₯Ό μˆ˜μ‹ ν•˜λ©΄ OnReceiveUserMessage() 이벀트 ν•¨μˆ˜κ°€ ν˜ΈμΆœλœλ‹€.

c->OnReceiveUserMessage = [...]
    (HostID sender, const RmiContext& rmiContext,
        uint8_t* payload, int payloadLength)
    {
        ... // μˆ˜μ‹ λœ 이벀트 처리λ₯Ό ν•΄ 주자.
    };

 

5. μ™€μ΄νŒŒμ΄ μ…€λ£°λŸ¬ μ—°κ²° ν•Έλ“œμ˜€λ²„ κΈ°λŠ₯

λͺ¨λ°”일 κ²Œμž„μ„ κ°œλ°œν•  λ•ŒλŠ” 무선 λ„€νŠΈμ›Œν¬κ°€ λŠμ–΄μ§ˆ 수 μžˆλ‹€λŠ” 점을 κ³ λ €ν•΄μ•Ό ν•˜λŠ”λ°, ν”„λΌμš°λ“œλ„·μ€ μ—°κ²° μœ μ§€ κΈ°λŠ₯을 톡해 이 문제λ₯Ό 극볡할 수 μžˆλ‹€. 이λ₯Ό μ‚¬μš©ν•˜λ©΄ μ™€μ΄νŒŒμ΄ 지역을 λ²—μ–΄λ‚˜κ±°λ‚˜ λ°˜λŒ€λ‘œ μ™€μ΄νŒŒμ΄ μ§€μ—­ μ•ˆμœΌλ‘œ 듀어가더라도 연결이 λŠμ–΄μ§€λŠ” ν˜„μƒ 없이 κ²Œμž„μ„ ν”Œλ ˆμ΄ν•  수 μžˆλ‹€.

param.m_autoConnectionRecovery = true;
...
c->Connect(param);

 

λ„€νŠΈμ›Œν¬ 톡신이 μΌμ‹œμ μœΌλ‘œ λ©ˆμΆ”κ³  λ‹€μ‹œ 회볡되면, κ·Έλ™μ•ˆ μ£Όκ³ λ°›μ§€ λͺ»ν–ˆλ˜ λ©”μ‹œμ§€λ₯Ό ν•œκΊΌλ²ˆμ— λ°›λŠ”λ‹€.

// λ„€νŠΈμ›Œν¬κ°€ μΌμ‹œ μ •μ§€λ˜μ—ˆμ„ λ•Œ
c->OnServerOffline = [...](CRemoteOfflineEventArgs &args) {
    // argsμ—λŠ” μ™œ μ˜€ν”„λΌμΈμ΄ λ˜μ—ˆλŠ”μ§€μ— λŒ€ν•œ 정보가 μžˆλ‹€.
    ...
};

// λ„€νŠΈμ›Œν¬κ°€ λ‹€μ‹œ νšŒλ³΅λ˜μ—ˆμ„ λ•Œ
c->OnServerOnline = [](CRemoteOnlineEventArgs &args) {
    // argsμ—λŠ” μ—°κ²° ν•Έλ“œμ˜€λ²„κ°€ μ™„λ£Œλœ ν›„ 정보가 담겨 μžˆλ‹€.
    ...
};

 

6. 원격 λ©”μ„œλ“œ 호좜

μ•žμ„œ μ‚΄νŽ΄λ³Έ 전톡적인 λ°©λ²•μœΌλ‘œ λ°”μ΄λ„ˆλ¦¬ 데이터 μ£Όκ³ λ°›κΈ°λŠ” μ†‘μˆ˜μ‹  루틴을 직접 λ§Œλ“€μ–΄μ•Ό ν•˜λŠ” λ²ˆκ±°λ‘œμ›€μ΄ μžˆλ‹€. ν”„λΌμš°λ“œλ„·μ˜ RMI(원격 λ©”μ„œλ“œ 호좜(Remote Method Invocation))은 μƒλŒ€λ°© 컴퓨터 μ•ˆμ— μžˆλŠ” ν”„λ‘œκ·Έλž¨μ˜ νŠΉμ • ν•¨μˆ˜λ₯Ό λ©€λ¦¬μ„œ μ‹€ν–‰ν•˜κ²Œ ν•˜λŠ”λ°, 이λ₯Ό μ‚¬μš©ν•˜λ©΄ λ”μš± νŽΈλ¦¬ν•˜κ²Œ 데이터λ₯Ό 주고받을 수 μžˆλ‹€.

  • 솑신을 μ²˜λ¦¬ν•˜λŠ” μ½”λ“œμ™€ μˆ˜μ‹ μ„ μ²˜λ¦¬ν•˜λŠ” μ½”λ“œλ₯Ό 일일이 κ΅¬ν˜„ν•  ν•„μš”κ°€ μ—†λ‹€.
  • μ†‘μˆ˜μ‹  λ©”μ‹œμ§€ ν˜•νƒœκ°€ λ³€κ²½λ˜μ—ˆμ„ λ•Œ μ†‘μ‹ μ΄λ‚˜ μˆ˜μ‹ μ„ μ²˜λ¦¬ν•˜λŠ” μ½”λ“œλ₯Ό μˆ˜μ •ν•˜λ‹€κ°€ μ‹€μˆ˜ν•  μœ„ν—˜μ΄ μ—†λ‹€.

 

RMI

 

RMIλŠ” μˆ˜λ™μœΌλ‘œ λ§Œλ“€μ—ˆμ–΄μ•Ό ν•˜λŠ” μ½”λ“œλ₯Ό μžλ™μœΌλ‘œ λ§Œλ“€μ–΄μ€€λ‹€. μ†‘μ‹ ν•˜λŠ” μͺ½μ—μ„œλŠ” μ‹€μ œ ν•¨μˆ˜ λŒ€μ‹  솑신을 λ‹΄λ‹Ήν•˜λŠ” μ½”λ“œκ°€ μ‹€ν–‰λ˜λŠ”λ°, 솑신을 λ‹΄λ‹Ήν•˜λŠ” μ½”λ“œλŠ” 'ν•¨μˆ˜ ν˜ΈμΆœμ„ λŒ€μ‹ ν•œλ‹€'λΌλŠ” 의미둜 proxy라고도 ν•œλ‹€. λ°˜λŒ€λ‘œ μˆ˜μ‹ ν•˜λŠ” μͺ½μ—μ„œλŠ” λ°›λŠ” λ©”μ‹œμ§€λ₯Ό λΆ„μ„ν•˜μ—¬ μ‹€μ œ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•΄μ€€λ‹€. μˆ˜μ‹ μ„ λ‹΄λ‹Ήν•˜λŠ” μ½”λ“œλŠ” 'ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•΄μ£ΌλŠ” 기반'μ΄λΌλŠ” 의미둜 stub라고도 ν•œλ‹€.

class SenderCode
{
    // μžλ™μœΌλ‘œ μƒμ„±λ˜λŠ” μ½”λ“œ
    Knight_Move(SendTo, position, motion)
    {
        Message msg;
        msg.Write(ID_Knight_Move);
        msg.Write(position);
        msg.Write(motion);
        Send(SendTo, msg);
    }
}

class ReceiverCode
{
    // μžλ™μœΌλ‘œ μƒμ„±λ˜λŠ” μ½”λ“œ
    ProcessReceivedMessage(Message msg)
    {
        ID = msg.Read();
        switch (ID)
        {
        case ID_Knight_Move:
            position = msg.Read();
            motion = msg.Read();
            Knight_Move(position, motion);
            break;
            ...
        }
    }
 
    Knight_Move(position, motion)
    {
       // 여기에 μ½”λ“œλ₯Ό μž‘μ„±ν•œλ‹€.
    }
}

 

7. ν΄λΌμ΄μ–ΈνŠΈλΌλ¦¬ P2P 톡신

ν”„λΌμš°λ“œλ„·μ—μ„œλŠ” μ„œλ²„ 없이 ν΄λΌμ΄μ–ΈνŠΈλΌλ¦¬ ν†΅μ‹ ν•˜λŠ” κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€. 이λ₯Ό P2P ν˜Ήμ€ ν”Όμ–΄νˆ¬ν”Όμ–΄ λ„€νŠΈμ›Œν‚Ήμ΄λΌ ν•œλ‹€.

  • μ„œλ²„κ°€ μŠΉμΈν•΄μ•Όλ§Œ P2P 연결이 κ°€λŠ₯ν•˜λ‹€. μ„œλ²„μ—μ„œ ν΄λΌμ΄μ–ΈνŠΈ 1κ³Ό 2λ₯Ό P2P μ—°κ²°ν•˜λΌκ³  μ§€μ‹œν•˜λ©΄, ν΄λΌμ΄μ–ΈνŠΈ 1κ³Ό 2λŠ” μ„œλ‘œκ°€ P2P 연결이 λ˜μ—ˆμŒμ„ μ¦‰μ‹œ μ•Œ 수 μžˆλ‹€.
  • μ΄ˆλŒ€λœ ν΄λΌμ΄μ–ΈνŠΈλ“€μ„ λ¬Άμ–΄ P2P 그룹이라 λΆ€λ₯Έλ‹€. 이 ν΄λΌμ΄μ–ΈνŠΈλΌλ¦¬λ§Œ P2P λ„€νŠΈμ›Œν‚Ήμ„ ν•  수 μžˆλ‹€.

 

P2P κ·Έλ£Ή

HostID list[2];
list[0] = C1;
list[1] = C2;
// 두 번째 인자 = λ°°μ—΄ 크기
G = s->CreateP2PGroup(list, 2);

 

8. μŠ€λ ˆλ“œ λͺ¨λΈ

μŠ€λ ˆλ“œ λͺ¨λΈ

 

ν”„λΌμš°λ“œλ„·μ€ μŠ€λ ˆλ“œ λͺ¨λΈμ„ 두 κ°€μ§€ ν˜•νƒœλ‘œ μ œκ³΅ν•œλ‹€.

  • μ„œλ²„ ν”„λ‘œμ„ΈμŠ€ ν•˜λ‚˜κ°€ μŠ€λ ˆλ“œ μ—¬λŸΏ κ°€μ§€λŠ” ν˜•νƒœμ˜ μ„œλ²„
  • μ—¬λŸ¬μ™€ μ—¬λŸ¬ μ„œλ²„ ν”„λ‘œμ„ΈμŠ€κ°€ 각각 μŠ€λ ˆλ“œ ν•˜λ‚˜λ₯Ό κ°€μ§€λŠ” ν˜•νƒœμ˜ μ„œλ²„

 

κΈ°λ³Έκ°’μœΌλ‘œ NetServer의 μ›Œμ»€ μŠ€λ ˆλ“œ(worker thread)λŠ” CPU 개수만큼 κ΅¬λ™ν•œλ‹€. λ‹€μ‹œ λ§ν•΄μ„œ CPU 개수만큼 μŠ€λ ˆλ“œλ₯Ό κ°€μ§„ μŠ€λ ˆλ“œ 풀이 기본으둜 μ œκ³΅λœλ‹€.

μ €μž‘μžν‘œμ‹œ (μƒˆμ°½μ—΄λ¦Ό)
'πŸ“ Book/✏ Game Server' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
  • [Book] κ²Œμž„ μ„œλ²„ ν”„λ‘œκ·Έλž˜λ° κ΅κ³Όμ„œ - 8μž₯ NoSQL 기초
  • [Book] κ²Œμž„ μ„œλ²„ ν”„λ‘œκ·Έλž˜λ° κ΅κ³Όμ„œ - 7μž₯ λ°μ΄ν„°λ² μ΄μŠ€ 기초
  • [Book] κ²Œμž„ μ„œλ²„ ν”„λ‘œκ·Έλž˜λ° κ΅κ³Όμ„œ - 5μž₯ κ²Œμž„ λ„€νŠΈμ›Œν‚Ή
  • [Book] κ²Œμž„ μ„œλ²„ ν”„λ‘œκ·Έλž˜λ° κ΅κ³Όμ„œ - 4μž₯ κ²Œμž„ μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈ
Blxxming
Blxxming
CS 지식과 κ³΅λΆ€ν•˜λ‹€ 배운 것, κ²½ν—˜ν•œ 것 등을 κΈ°λ‘ν•˜λŠ” λΈ”λ‘œκ·Έμž…λ‹ˆλ‹€.
  • Blxxming
    πŸ’‘λ²ˆλœ©πŸ’‘
    Blxxming
  • 전체
    였늘
    μ–΄μ œ
  • 곡지사항

    • Tech Interview
    • πŸ“š Tech (246)
      • πŸ“ Computer Science (96)
        • ✏ OS (12)
        • ✏ Network & Web (10)
        • ✏ Database (11)
        • ✏ Data Structure (6)
        • ✏ Algorithm (40)
        • ✏ Design Pattern (9)
        • ✏ Cloud Computing (3)
        • ✏ (5)
      • πŸ“ Language (73)
        • ✏ Language (6)
        • ✏ C & C++ (11)
        • ✏ C# (19)
        • ✏ JAVA (37)
      • πŸ“ Game (43)
        • ✏ Computer Graphics (2)
        • ✏ Unity (14)
        • ✏ Unreal (26)
        • ✏ (1)
      • πŸ“ Book (34)
        • ✏ Effective (3)
        • ✏ Game Server (16)
        • ✏ Clean Code (14)
        • ✏ (1)
  • hELLOΒ· Designed Byμ •μƒμš°.v4.10.0
Blxxming
[Book] κ²Œμž„ μ„œλ²„ ν”„λ‘œκ·Έλž˜λ° κ΅κ³Όμ„œ - 6μž₯ κ²Œμž„ λ„€νŠΈμ›Œν¬ μ—”μ§„ ν”„λΌμš°λ“œλ„·
μƒλ‹¨μœΌλ‘œ

ν‹°μŠ€ν† λ¦¬νˆ΄λ°”