강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

Dodontak님의 프로필 이미지
Dodontak

작성한 질문수

[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part5: UE5 & IOCP 서버 연동

쓰레드

recv 할게 없어도 무한 while문을 도는데 괜찮은건가요?

작성

·

37

0

uint32 RecvWorker::Run()
{
	while (Running)
	{
		TArray<uint8> Packet;
		if (ReceivePacket(OUT Packet))
		{
			/*패킷을 큐에 등록*/
		}
	}
	return 0;
}

bool RecvWorker::ReceivePacket(TArray<uint8>& OutPacket)
{
	// 패킷 헤더 파싱
	const int32 HeaderSize = sizeof(FPacketHeader);
	TArray<uint8> HeaderBuffer;
	HeaderBuffer.AddZeroed(HeaderSize);

	if (ReceiveDesireBytes(HeaderBuffer.GetData(), HeaderSize) == false)
		return false;
        /*...*/
}

bool RecvWorker::ReceiveDesireBytes(uint8* Results, int32 Size)
{
	uint32 PendingDataSize;
	//연결 종료되면 packetrecvsize 0으로 옴 -> 연결 끊겼으면 종료.
	if (Socket->HasPendingData(PendingDataSize) == false || PendingDataSize <= 0)
		return false;
	/*...*/
}

recvworker 쓰레드를 만들고 run이 실행됐는데 커널의 recv버퍼에 읽을게 없을 때

  1. 헤더확인을 위한 ReceiveDesireBytes 호출

  2. Socket->HasPendingdata() 에서 return false

  3. ReceiveDesireBytes 에서 return false

  4. Run에서 ReceivePacket return false로 recv할게 올때까지 while문 무한반복

이렇게 되는데 while문이 의미없이 무한반복하고 있는게 좀 걸려서 질문합니다.

recv가 계속 올거라 상관이 없어서 이렇게 처리해도 큰 상관이 없는건가요?

그게 아니면 혹시 Socket->Recv 에서 블로킹이 걸리게 만들어놓고 쓰레드는 대기하다가 서버로부터 읽을게 오면 알아서 블로킹이 풀리고 일을 하도록 하는건 별로인가요?

답변 2

0

Rookiss님의 프로필 이미지
Rookiss
지식공유자

네 조금 더 주기적으로 체크해도 무방하고,
네트워크 부분만 별도의 쓰레드로 확실히 관리할 경우 블로킹 방식으로 가도 괜찮습니다.

0

안녕하세요, 인프런 AI 인턴입니다. Dodontak님.

현재의 RecvWorker 쓰레드 코드에서 서버로부터 데이터가 없을 때 무한루프가 발생하는 부분이 걱정이신 것 같습니다. 이 문제는 서버에 데이터가 없는 경우에도 CPU를 계속 사용하게 되어 성능에 좋지 않을 수 있습니다.

이 문제를 해결하기 위해 몇 가지 방법을 고려할 수 있습니다:

  1. Non-blocking Socket 사용: Socket->HasPendingData 함수가 데이터를 기다리면서 블로킹되도록 하고 데이터를 받으면 작업을 수행하도록 수정할 수 있습니다. 이를 통해 데이터를 받을 때까지 CPU 사용을 줄일 수 있습니다.

  2. Sleep 사용: 데이터가 없는 상황에서 while 루프 사이에 Sleep 함수를 사용하여 쓰레드가 잠깐 휴식을 취하도록 할 수 있습니다. 일정 시간 대기한 후 다시 데이터를 확인하도록 수정하는 것입니다.

  3. Event-driven Programming: Windows에서는 IOCP(Input/Output Completion Ports)를 활용하여 서버가 이벤트 기반으로 동작하도록 할 수 있습니다. 이는 데이터가 도착할 때만 쓰레드가 활성화되도록 하여 시스템 자원을 효율적으로 사용하게 도와줍니다.

이러한 방법들은 각기 다른 장단점이 있으니, 시스템 요구사항과 성능을 고려하여 적절한 방식을 선택하시길 바랍니다.

비슷한 주제의 질문은 다음 링크에서도 확인하실 수 있습니다:
- 혹시 언리얼 클라에서는 WSA Recv가 아니라 그냥 recv 사용해야 하나요?
- 패킷 리시브버퍼 관련 질문이 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

Dodontak님의 프로필 이미지
Dodontak

작성한 질문수

질문하기