묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요. CV Producer() 내부의 lock 스코프 안에서 cv.notify_one()하는 것 질문드립니다.
CV Producer() 내부의 lock 스코프 안에서 cv.notify_one()하는 것 질문드립니다.그 안에서 notify_one()을 하게 되면 확실히 큐에 푸시한 후에 다른 스레드가 가로채기 전에 notify_one을 호출하니 Consumer()의 wait()에서는 확실하게 q에 값이 있는 상태가 되는 것 아닌가요? notify_one()을 한 후 Producer를 호출한 스레드는 스코프를 바로 빠져나올거고, 빠져나오면서 lock을 놓아줄 거고 그러면 놓아주는 순간 Consumer()의 wait는 누가 가로채기 전에 바로 들어오니 가짜 기상 문제가 해결되는 것 아닌가요. 아리달송합니다..
-
해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
VS 2022 기준 ServerCore의 .lib 파일을 못찾을 수 있나요?
루키스님 안녕하세요?vs 2022에 맞춰서 IOCP 구축연습 밑바닥 부터 하고있습니다. 역시 환경 설정부터 난관이었는데요,ServerCore의 .lib파일을 GameServer가 못찾습니다 (ServerCore 빌드까지는 됩니다)강의 몇번을 돌려봐도 안되길래 좀 찾아보니까pch.h에 절대 경로를 넣어서 찾아주거나(근데 이건 아니다 싶어서)#ifdef _DEBUG #pragma comment(lib, "C:\\CppGameServer25\\CppGameServer25\\GameServer\\Libraries\\Debug\\ServerCore.lib") #else #pragma comment(lib, "Release\\ServerCore.lib") #endif강의에서 더해서 GameServer의 추가 라이브러리 디렉토리를 설정해줘야지만 .lib 파일을 찾고 GameServer가 빌드할 수 있었습니다. 일단 되니까 다행이긴 한데,됐으니까 장땡인지, 아니면 제가 경로 설정? 환경 설정?등 알아둬야 하거나 놓친 것이 있는지 조언 구하고 싶습니다.왜 강의대로만 하면 안되고 추가 라이브러리 디렉터리를 설정해줘야지만 빌드가 되는지 원리에 대해 궁금합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
RegisterRecv()가 멀티스레드 환경에서 안전하다는 게 이해가 가지 않습니다.
안녕하세요 선생님. 선생님 강의 덕분에 요즘 서버 개발이 너무 재밌습니다. 감사합니다. 다름이 아니라 이해가 안가는 부분이 있어서 질문드립니다.1:20 초에 RegisterRecv()는 멀티스레드 환경에서 안전하다고 하셨는데 이 부분이 이해가 가지 않습니다.AcceptEx()를 걸고 나서 만약 클라이언트가 5개 붙으면 ProcessAccept()는 5번 호출될 것이고, 호출될 때마다 ProcessConnect()를 내부에서 호출하여 WSARecv()는 연결된 클라이언트마다 1번씩 호출하게 되는 것으로 코드를 이해했습니다. 그렇다면 클라이언트가 5명 붙는다면 WSARecv()는 5번 호출될텐데, 각 클라이언트가 동시에 send한다면 서버는 GetQueuedCompletionStatus()를 통과하여 동시다발적으로 ProcessRecv()를 호출할텐데 이 때 멀티스레드 critical section 문제가 발생할 것 같은데 제가 잘못 이해한 부분이 있을까요?혹시 client 별로 한 개 씩 RegisterRecv()를 등록해 놨으므로 각 client들은 각자 등록한 WSARecv()에만 연결되는 것이라서 멀티스레드 문제가 안 생긴다는 뜻일까요?
-
해결됨[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part5: UE5 & IOCP 서버 연동
이동동기화 관련 질문 드립니다. 추측항법 외.
안녕하세요 루키스님. 지금은 C#서버로 칸 없이 3D 이동 동기화 토이프로젝트 여러모로 시도해보고 있습니다.제 토이 프로젝트의 목적은추측항법을 사용해 칸 없이 3D 이동 동기화로써 루키스님 강의들 Q&A 뒤적여서 이해한 추측 항법은 "목적지를 뿌려주고 거기로 어떻게 하던지간에 이동하게 해준다" 로 다음 아이디어를 적용해보게 되었습니다. 기본 아이디어는 플레이어 A가 [0,0,0]에 있다면, 바라보는 방향으로 벡터1 만큼을 더한 위치, 예를 들어 w를 누르면 [1,0,0]의 C_Move 요청 패킷을 날리고, 서버가 모든 유저들에게 브로드캐스팅 해주면,각 클라이언트는 A의 위치를 [0,0,0] 에서 [1,0,0]으로 자연스러운 Transform 변경으로 '스르륵'을 구현했습니다.// 참고용 위치 동기화 핵심 코드 void Update() { // destinationPos : S_Move패킷을 통해 갱신된 목표 위치 float distance = Vector3.Distance(transform.position, destinationPos); // 목표지점에 거의 다왔으면 목표 위치로 순간이동 if(distance < 0.1f) { transform.position = destinationPos; } else { // 스르륵 이동 transform.position = Vector3.MoveTowards(transform.position, destinationPos, Speed * Time.deltaTime); } // TODO : 보정 등 } 현재 C++ 서버도 병행해서 공부하는 저의 시점에서, 몇가지가 궁금해서 질문 드리게 되었습니다.Q1. 지금 강의, IOCP와 UE5에서 소개해주신 이동 동기화를 추측항법은 아닌 것으로 이해됩니다(과거 위치를 브로드캐스팅 해주고 있으므로). 제가 이해한게 맞을까요? Q2. 제가 구현한 아이디어와 코드도 일종의 추측항법이라고 우겨도 될까요? 포트폴리오 키워드로 녹이고 싶은 욕심이 있습니다. Q3. 제가 채택한 이동 동기화의 방법의 피드백도 가능하다면 받고 싶습니다. 위 코드에 보정은 어느 정도 넣을 예정이지만, 기본 아이디어에 대해 시니어님의 의견도 여쭈고 싶습니다. 차기 강의 항상 기대하고 있습니다 ㅎㅎ 몸은 다 나으셨는지 모르겠네요.답변 미리 감사합니다!
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
ThreadManager.h 관련 질문있습니다.
제 ThreadManager.h 소스코드입니다.이 부분과 Types.h 소스코드를 포함하여 다른 모든 코드가 강사님의 코드와 같습니다.근데 저는 이상태로 빌드하면 이러한 컴파일오류들이 발생합니다.해결방법을 찾다가 제 ThreadManager.h 소스코드부분을std::functionstd::mutexstd::vecotr<std::thread>로 바꾸면 해결이 되긴합니다.하지만 강사님의 소스코드와 같이 std를 붙이지않았을때는 왜 제 코드에선 빌드오류가 나는지 원인을 모르겠습니다.types.h에 강사님이 작성하신 using을 이용한 코드들 똑같이 작성되어있고 CorePch.h에 using namespace std; 문장또한 존재하며 CorePch.h와 Pch.h include도 빼먹지 않았습니다.. 이유를 몰라 잠이안옵니다 ㅠㅠ..
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
1:48 초에 패킷의 수 말씀하셨는데
일반적인 포트폴리오는 10~20개라이브에서는 100~200개면너무 적은 거 아닌가요? 스킬만 처리해도 되게 많은 패킷이 필요할 것 같은데일반화를 잘해서 패킷 구조 하나로도 많은 부분을 처리한다던지?.. 그런 건가요
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
35분 06초 질문 있습니다.
복사될때 RefCount가 1증가해서 넘어가기 때문에사용중에는 삭제되지 않을것이라는 보장이 있다고 말씀해주셨는대다른 쓰레드가 해당 메모리를 해제하면 삭제가 되는것 아닌가요?? 이부분이 잘이해가 안가서 질문드립니다.다시 말씀드리자면 어떻게 상호배제가 구현되는지 잘 이해가 가지 않습니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
ClientService의 Start와 Send
안녕하세요. 세션관련해서 궁금한 점이 있습니다.ClientServiceRef service를 생성해서 connect를 하는데요,이 service로 Start하는 과정이 궁금합니다. Start 함수 내부에서 sessionCount만큼 Connect를 하는데 클라이언트는 서버에 한 번만 Connect를 하면 될 텐데 maxSessionCount만큼 연결 시도하는 것은 무슨 이유인가요? 그리고 service를 생성한 후 Broadcast를 하는데 연결된 서버는 하나인데, 맥스 세션 수만큼 Broadcast를 하는 것도 이해가 안 가네요. 만약 Broadcast가 아니고 그냥 Send 함수를 구현한다면 맥스세션 수 내의 세션 중에서 어떤 세션에 Send를 호출해야 할까요?답변 부탁드립니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part5: UE5 & IOCP 서버 연동
이 시리즈 25년에 계획 있으실까요?
C++도 C# Part7+Part9 처럼게임 구현하고 서버에 물리는 과정까지 하실 예정 있으신지 궁금합니다. 다른 게시글에서 나~~중에 한다고 하신걸 봤는데 25년에는 계획이 있으신가요?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
강의 다 듣고 와서 락 관련 질문드립니다.
강의 잘 들었습니다🙏락을 구현할 때 ReadLock을 만들었는데 전체 강의 코드를 보면 ReadLock을 사용하는 데가 없더라고요(DB 쪽은 스킵했습니다). 우리 프로젝트에만 해당하는 특별한 경우인지 실무에서도 WriteLock 사용이 압도적으로 높은 것인지 궁금합니다.락을 직접 구현한 이유 중 하나가 (동일 스레드 기준) 쓰기 락이 걸려있을 때 읽기를 허용하기 위한 것도 있었는데, 읽기 락을 만들어놓고 한 번도 사용하지 않았다는 사실이 약간 신기하게 느껴졌습니다.+) 답변하시기 전에 추가 질문서두에 말씀하신, 직접 락을 구현하는 이유가, 기획 데이터는 대부분 읽기를 수행하는데(잘 안 바뀌는 데이터), 굳이 스레드 간에 상호배타적일 필요가 없기 때문에(표준을 이용한 방법이 있으나), 읽기에 대해선 모든 스레드가 접근할 수 있게 ReaderLock이 필요한 걸로 이해했습니다.그렇다면 운영에서 기획 데이터에 아이템을 추가한 걸 화면에 보여줘야 할 때는, WRITE_LOCK이 사용되나요?..기획 데이터를 실시간으로 읽어오는 건지 업데이트를 하면 서버를 재시작하는 건지 궁금합니다. 실무 경험이 없다 보니까 기획 데이터로 예를 들어주실 때 상황이 명확하게 안 그려지네요. 서버를 재시작하는 거라면 이미 변경된 데이터를 서버 구동 때 읽어오는데 쓰기 락이 왜 필요한지 궁금합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
DoGlobalQueueWork함수에 관한 질문입니다!
안녕하세요.이전 질문 중에 DoGlobalQueueWork가 실행되면서 GlobalQueue에서 일감을 꺼내 멀티스레드 환경에서 처리되는 도중에, 데이터가 겹쳐 레이스 컨디션이 발생할 수 있냐는 질문에 강사님께서 멀티스레드 이슈가 다시 생길 수도 있다고 말씀하셨습니다. 관련해서 궁금한 점이 생겼습니다.적어도 저희 강의에 적용된 코드에 국한해서, 데이터가 겹친다는 이유로 레이스 컨디션이 발생할 수 없지 않나요? GlobalQueue로 데이터를 넣고 빼는 부분에 락을 거니까 해당 부분에서는 아주 잠깐의 락 대기 시간이 생길 수 있고, 일감을 일단 Pop한 이후에는 데이터가 겹치는 일이 생길 수 없는 것 같은데, 이전 답변을 보고는 생길 수 있는 가능성이 없지 않다는 느낌을 받아서 이 궁금증을 해소하고 싶습니다~이전 질문에서 답변해주신 것 중에 Zone 단위로 JobQueue를 배치하는 경우 데이터 공유가 거의 없고 Actor 단위일 경우엔는 필연적으로 순간에 Lock을 걸거나, 정밀 조정이 어려우니까 그냥 락 걸지 않고 데이터를 get할 수 있다는 내용은 이해했습니다!
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
운영체제에 구애받지 않는 네크워크 모델
너무나 알찬 수업 잘 듣고있습니다.수업들 듣던 중, 의문이 하나 생겨서 질문남깁니다. 네트워크 라이브러리중, boost::asio 를 이용해서 운영체제에 독립적인 환경을 구축할 수 있을거 같은데,네트워크 부분은 윈도우 맞춤으로 수업하시는 이유가 궁금합니다. boost::asio 의 기능만으로는, 효율적인 게임서버를 구축하기 어려워서 인가요?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
서버 컨텐츠 제작
선생님 제가 파트5를 아직 안 본 상태인데파트4 내용으로 기반을 잡은 상태에서제가 마음대로 이어서 만들면 되지만이어서 파트5에서는 언리얼과 연동하면서정석적인 컨텐츠 개발 설계를 배울 수 있는 걸까요?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
서버 중지 기능
안녕하세요. 서버를 중지하고자 하면 어떤 절차를 거쳐야 하나요? Listener
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
DB에서 플레이어 정보를 긁어오는 부분에 대한 질문입니다!
안녕하세요!16:02에서 플레이? 플레이어 정보를 DB에서 긁어온다고 하셨는데요. DB에서 특정 유저의 정보를 가져오려면 unique id, id+password 조합이든, 식별 값이 필요할 거라 생각합니다. 이는 DummyClient OnConnected()에서 C_LOGIN 패킷을 만들 때 함께 보내줘도 될까요? 만약 그렇다면,로그인은 웹 등의 게임 외부 환경에서 먼저 진행될텐데, 웹 등의 외부 환경에서 로그인 성공 이후 게임 파일을 실행할 때 id, password(해싱된 값)를 같이 넘겨주고 그 정보로 Handle_C_LOGIN에서 해당 유저의 정보를 가져오면 되는 걸까요?제가 C# 강의 해당 강의까지는 들을 여력이 안 돼서, 여쭙습니다. C# 클라 <-> C++ 서버 헤딩할 때 적지 않은 시간이 쓰일 거 같아, 구현하지 않는 부분에 대해서는 흐름이라도 명확하게 가져가려고 합니다.
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Protobuf Packet 클라이언트 - 서버 설계
서버에서 Protobuf를 사용하고클라이언트에서 예기치 못한 이유로 사용하지 못했을 때주고 받는 Packet.id그리고 그 id에 해당하는 정보(구조체)가 같다면상관 없을 까요?ex)서버 -> S_CHAT : string msg; 구글 프로토버프로 만듬클라이언트 -> S_CHAT : string msg: 일반 구조체로 만듬
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
iocp 내부 동작 관련 질문
Windows IOCP(I/O Completion Port) 모델을 사용하여 서버를 개발하고 있으며, WSASend 호출의 처리 순서에 대해 명확히 알고 싶습니다.1. WSASend 호출 순서 보장 - 서버에서 연속적으로 WSASend를 3번 호출할 경우, Windows 내부에서 정확히 호출된 순서대로 처리되는지? - TCP의 순서 보장과는 별개로, IOCP 모델 자체의 내부 처리 순서는 어떻게 되는지?2. 클라이언트 측 완료 통지 순서 - 서버에서 WSASend를 3번 호출했을 때, 클라이언트가 GetQueuedCompletionStatus(GQCS) 함수를 호출하면 서버의 호출 순서와 동일한 순서로 완료 통지가 수신되는지?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
채팅실습 과정에서 Protocol.pb.h error
채팅실습을 시작해서 BufferData 구조체를 삭제하고빌드를 하게 되면 파일은 복사가 되어서 다른 패킷아이디들이 생성되는데지웠던 BufferData가 계속해서 BufferData가 없다는 에러가 발생하고실제로 Protocol.pb.h에 남아있는 현상이 발견됩니다..이런 증상 겪으신분 있으실까요?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
보편참조 관련 질문
강의 내용 22:00에 보편참조라고 설명해 주시면서Job 생성자를 만들어주셨습니다.하지만 Job생성자는 우측값 참조가 아니면 생성이 되지 않습니다.반면에 우측값 참조로 넣어주면 전부 에러 없이 생성되었습니다Job 생성자가 보편참조라면 좌측값인 player로도 생성이 되어야 하지 않나요? 만약 Job 생성자가 보편참조가 아니라면GRoom->PushJob(&Room::Enter, player) 부분에서보편참조가 아닌 함수에서 L-value를 std::forward를 사용하면 오른쪽 참조값으로 바뀌기 때문에 auto job = ObjectPool<Job>::MakeShared(owner, memFunc, std::forward<Args>(args)...);이함수는 결국 우측값 참조를 받는 Job생성자를 호출하게 되어 Job을 만들어 주었기 때문에 에러가 발생하지 않고 잘 실행 되었던거라고 이해하면 될까요? 만약 Job생성자가 보편참조가 아니라면 왜 보편참조가 될 수 없나요? 강의 핵심내용은 JobQueue에 관한 내용이지만보편참조가 너무 헷갈려서 질문하게 되었습니다..
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
boost asio 강의
안녕하세요 루키스님혹시 작년에 진행했던 javawork 님의 boost asio 강의는인프런에 판매하실 생각은 없으신 건가요??