TIL_072 : 전위/후위 연산자, 서버 디버깅, 클라접속막기, 네트워크 연결 후 불리는 함수

김펭귄·2025년 11월 27일

Today What I Learned (TIL)

목록 보기
72/93

오늘 학습 키워드

  • 전위/후위 연산자

  • 서버 디버깅

  • 클라 접속 막기

  • NetConnection

1. 전위/후위 연산자

  • 단항 연산자로, 전위는 먼저 1을 더해주고 l-value를 반환해주고, 후위는 먼저 r-value를 반환하고 식 계산이 끝난 후 1을 더해줌

  • 그래서 ++a = 5;는 되지만, a++ = 5;는 안 됨

  • 포인터의 경우는 각 포인터의 자료형크기를 계산해서 더해줌
    int*에 전위/후위 연산자를 하면, int가 4byte이므로 4byte를 더해줌

  • 이렇게 작은 객체들에서는 성능차이가 별로 없는데 iterator에서 차이가 극명해짐

  • 후위의 경우, 항상 새로 메모리로 복사해야하므로 성능이 좀 떨어짐

  • 그래서 왠만하면 후위보단 전위를 사용하는게 좋음

  • 그리고 컴파일러마다, C++버젼마다 또 내부 동작방식이 달라지므로, 복잡하게 사용하면 안 됨.

2. 서버 로그 찍기

  • Dedicated서버의 경우, 이전 설정에서 launch separate servertrueRun Under One Processfalse로 하였으나 이러면 서버가 따로 실행되기에 서버로직을 디버깅할 수 없음

  • 그래서 서버로직을 디버깅하려면 이 2개의 값을 다시 반대로 해주면 됨

3. 클라이언트 접속 막기

  • 클라이언트가 서버에 접속한 이후 PostLogin()이 호출되었었음

  • 만약 클라이언트의 접속을 막고 싶으면 PreLogin()함수에서 ErrorMessage를 수정해주면, 클라이언트는 접속이 막히고 StandAlone NetMode로 혼자 실행됨

  • 따라서 게임모드 생성자에 로그찍어보면, 먼저 서버에서 게임모드가 만들어진 후, 클라가 접속요청하지만 막혀서 자기 혼자 싱글플레이어로 실행되면서 게임모드 하나 또 생김.

  • 서버에 접속되었으면 서버에서만 하나 생성되지 클라에서는 원래 생성 안 됨

void ADXGameModeBase::PreLogin(const FString& Options,
							   const FString& Address, 
                               const FUniqueNetIdRepl& UniqueId,
                               FString& ErrorMessage)
{
	Super::PreLogin(Options, Address, UniqueId, ErrorMessage);

	ErrorMessage = TEXT("The server is currently full. Please try again later.");
    // StandAlone으로 혼자 실행됨
}

4. NetConnection

  • 저번에 공부했던 서버와 클라의 NetConnection확인해보기

4.1. 서버의 NetConnection

  • 서버에서 ClinetConnection을 보려면, 먼저 클라가 접속완료되면 호출되는 AGameModeBase::PostLogin()에서 확인

  • 게임모드는 서버밖에 없으니, 서버에서의 NetConnection을 확인 가능

  • 좀 더 자세한 NetDriver 구조는 velog

void ADXGameModeBase::PostLogin(APlayerController* NewPlayer)
{
	Super::PostLogin(NewPlayer);

	// 서버의 NetDriver 가져오기
	UNetDriver* ServerNetDriver = GetNetDriver();
	if (IsValid(ServerNetDriver))
	{
    	// 클라이언트 없을 때
		if (ServerNetDriver->ClientConnections.Num() == 0)
		{ /* ... */ }
		else	// 클라이언트 있을 때
		{
        	// NetDriver에 있는 각 ClientConnection들 가져오기
			for (const auto& ClientConnection : ServerNetDriver->ClientConnections)
			{
				if (IsValid(ClientConnection) == true)
                	// 각 ClientConnection들의 이름
                	FString Name = *ClientConnection->GetName();
			}
		}
	}
    
    else	// NetDriver가 없는 상황. 즉, StandAlone 상태
    { /* ... */ }
}

4.2. 클라의 NetConnection

  • 클라이언트의 경우는 액터들의 모든 네트워크 초기화가 다 끝나면 APlayerController::PostNetInit()함수가 호출됨

  • 그래서 이 함수에서 LocalController일 경우에만 NetConnection을 확인하면 그것이 클라이언트의 것

void ADXPlayerController::PostNetInit()
{
	Super::PostNetInit();
	
	if (IsLocalController()) // 클라이언트일 때만
	{
		UNetDriver* ClientNetDriver = GetNetDriver();
		if (IsValid(ClientNetDriver))
		{
			UNetConnection* ServerConnection = ClientNetDriver->ServerConnection;
			if (IsValid(ServerConnection)) {} // 서버와 접속된 클라이언트
			else {} 	// 리슨 서버
		else 			// StandAlone
	}
}

4.3. 로그 결과

  • 클라이언트 한 명만 접속한 상태일 때

  • 새 클라 접속한 이후 (서버는 ClientConnection 2개, 각 클라는 ServerConnection1개 가짐)

profile
반갑습니다

0개의 댓글