서버와 클라이언트

서버 시작하기

서버를 시작하기 위해 먼저 아래 예시처럼 서버 객체를 얻어야 합니다. 서버를 생성하자마자 클라이언트와의 통신을 하거나 스레드 풀이 바로 생성되진 않으므로 생성된 객체의 Start를 호출해서 서버를 실행해야 합니다.

1. 서버 생성

m_netServer = Proud::CNetServer::Create();
// 힐딩된 객체는 delete 연산자로 제거할 수 있습니다. 
delete m_netServer;

서버를 시작하기에 앞서, 서버의 UDP 포트 방식을 반드시 확인해 주시기 바랍니다.

2. 준비

// ProudNet을 include 합니다.
#include “include\ProudNetServer.h”
  
// ProudNet은 모든 객체가 Proud라는 namespace로 묶여 있습니다.
using namespace Proud;
  
// port 정의
int g_ServerPort = 33334;

3. 서버 시작

먼저 서버 객체를 생성한 후 SetEventSink 함수를 호출합니다. 서버에서 일어나는 이벤트를 콜백받기 위한 객체를 등록하는 과정입니다. INetServerEvent 객체를 상속받아 생성한 객체의 포인터를 넘겨주게 되면 서버는 이 객체를 통하여 이벤트를 콜백합니다.

c++ 11 이후부터는 SetEventSink 대신 람다를 사용한 이벤트 등록이 가능합니다.

// c++ 11 이전 버전만 참고해 주세요.
// g_eventSink는 INetServerEvent를 상속받은 객체입니다.
CNetServer* srv = 
         Proud::CNetServer::Create();
srv->SetEventSink(
         &g_eventSink);
  
// 서버 시작에 필요한 파라미터 설정합니다.
CStartServerParameter p1;
 
// Client 의 Connection을 받을 Port
p1.m_tcpPort = 33334;  
  
srv->Start(p1);

💡위 코드 예시에서 g_eventSink 가 아래 구조로 생성된 객체입니다.

// CNetServer로부터 이벤트를 받을 객체 생성 방법
Class CServerEventSink 
         : public INetServerEvent 
{
       // Client의 접속이 완료되면 
       // Callback됩니다.
       // CNetClientInfo 객체를 인자로 받습니다. 
       Virtual void OnClientJoin(
           CNetClientInfo *info) 
           OVERRIDE
       {
           // Client의 정보를 받아 
           // 처리합니다.
       }
       // Client의 접속이 해제되면 
       // Callback됩니다.
           Virtual void OnClientLeave(
               CNetClientInfo *info) 
               OVERRIDE
       {
               // Client의 정보를 받아 
               // 처리합니다.
       }
       // 나머지 Event는 생략
}

CNetClientInfo 객체는 접속된 클라이언트 정보를 포함하며, CNetClientInfo의 멤버 m_HostID는 각 호스트를 구분할 수 있는 ID값이 됩니다.

💡C#에 NetClientInfo가 C++의 CNetClientInfo와 같은 역할을 합니다.

4. 연결 해제

함수설명

Stop

서버 정지. 모든 Connection을 끊습니다.

CloseConnection(Client의 HostID)

해당하는 클라이언트와의 접속을 끊습니다.

5. 클라이언트 연결받기 시작

서버에서 클라이언트 연결을 받기 위해서는 서버 측 리스닝 포트(Listening Port)와 스레드 풀을 준비합니다. 그러기 위해, Server 객체를 생성한 후, Start 메서드를 호출해야 합니다.

클라이언트 시작하기

서버와 마찬가지로 클라이언트 또한 객체 생성 후 서버와 연결이 가능합니다.

1. 클라이언트 생성

m_netClient = Proud::CNetClient::Create();

2. 준비

// 서버 연결에 필요한 parameter 설정
Proud::CNetConnectionParam cp;

// 서버와 같은 protocol 버전을 입력해야 한다. 아예 입력하지 않을 수도 있음.
cp.m_protocolVersion = g_version;
cp.m_closeNoPingPongTcpConnections=false;
cp.m_serverIP = _PNT("localhost");
cp.m_serverPort = 33334;	

3. 시작

// 위 준비 예시에서 만들어 둔 parameter를 사용
m_netClinet->Connect(cp);

클라이언트에서 서버에 연결하는 동안 발생하는 이벤트

  • Connect 가 실행되면 서버에는 OnConnectionRequest 가 도착하는데 여기서 연결을 시도하는 클라이언트를 거부할 수 있습니다.

  • OnConnectionRequest 에서 클라이언트 연결을 수용하면 모든 연결 과정을 마치게 되며, 클라이언트와 서버에서는 아래 코드 예시처럼 이벤트를 받게 됩니다.

// 서버에서
m_netServer->OnClientJoin = [](CNetClientInfo *clientInfo){
    // Client Join 시 실행할 로직
};

// 클라이언트에서
m_netClient->OnJoinServerComplete = [&](ErrorInfo *info, const ByteArray &replyFromServer) {
    // Server 연결 완료 시 실행할 로직
}

4. 연결 해제

// 서버와의 연결 해제
m_netClient->Disconnect();


활용

page서버 활용법page클라이언트 활용법

Last updated