월 66,000원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
스핀락 질문입니다
while(_locked.compare_exchange_strong...) { //블라블라 } 부분에서 저 코드가 예시인건 알겠지만 현업에서는 while문 안에서 어떤 별도의 작업을 하게 하는 경우가 있나요? 있다면 보통 어떤 목적으로 사용하는 경우가 많나요?? 그리고 이건 약간 별도의 질문인데 이 강의로 서버파트를 공부할 때 처음부터 끝까지 한번 씩 쫙 들으면서 전반적인 흐름을 파악하고 다시 한번 하면서 깊게 들어가는 방법과 하나씩 하나씩 완벽하게 습득한 후에 다음 개념을 습득하는 방법중 더 추천하는 방법이 있으신가요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
atomic 클래스를 다른 클래스와 사용한다면
atomic<int> atomic_int의 수정은 atomic_int.store() 함수를 이용해서 atomic하게 값 assignment가 가능한데 예를 들어 직접 정의한 Person 클래스의 name등과 같은 여러 맴버변수를 atomic하게 수정할 때 사용하는 함수가 있을까요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
좋은 강의 감사합니다
좋은 강의 감사드립니다 1.혹시 언리얼과 서버 강의 연동을 내년에 출시하실 예정이라고 하셨는데 계획에는 혹시 변경이 없나요? 언리얼엔진5와 서버연동을 많이 기대하고있습니다 2.예전에 제가 혼자 서버와 언리얼을 연동할 때는 언리얼에 Winsock을 추가하는 방식으로 제작해서 크래쉬가 좀 많이 일어났었는데 강의를 듣고보니 더 좋은 방법이 있을꺼 같은데 연동할 때는 어떤 방식으로 진행을 하나요? 마지막으로 혼자 서버 제작할때는 단순 노가다식 코드로 했었는데 강의듣고 난 후에는 서버코어 라이브러리 부터 받아오는 방식과 메모리 관리/자동화 코드를 배운 덕분에 코드가 많이 좋아지고 편해졌습니다 항상 좋은 강의 감사드립니다
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
_parent[now]가 음수 인덱스로 확인됩니다.
안녕하세요. 로그를 찍히는 부분에서 에러가 나서 확인을 했더니 _parent[now]값이 -1인덱스라 _idToName 인덱스 접근할 때 잘못 접근하는거 같은데요. 이부분은 버그를 수정해서 진행해도 되는게 맞는지 문의 드려요.
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
락만 뮤텍스로 바꿨을뿐인데 프로그램이 죽습니다
락 부분이 좀 어려워 흔히 쓰는 뮤텍스 방식으로 수정해보았습니다. 사진은 하나만 넣었지만 WRITE_LOCK을 쓰는 모든 부분을 위와같이 수정했습니다. 하지만 위와 같은 에러가 나오는걸로 보아 멀티쓰레드 동기화 문제로 보입니다. 혹시 선생님이 쓰신 락이랑 뮤텍스 기반 락이랑 어떻게 다르기에 평범한 락으로 바꿨더니 프로그램이 죽는걸까요? (혹시 안보이시면 우클릭 -> 새 탭에서 이미지 열기 해주시면 잘보일거에요)
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
작업 환경에 따라 에러가 있고 없고 합니다.. 이틀째 해결이 안되요 ㅜㅜ
GameServer 프로젝트 void Listener::RegisterAccept(AcceptEvent* acceptEvent) { SessionRef session = _service->CreateSession(); // Register IOCP acceptEvent->Init(); acceptEvent->session = session; DWORD bytesReceived = 0; if (false == SocketUtils::AcceptEx(_socket, session->GetSocket(), session->_recvBuffer, 0, sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16, OUT & bytesReceived, static_cast<LPOVERLAPPED>(acceptEvent))) { const int32 errorCode = ::WSAGetLastError(); if (errorCode != WSA_IO_PENDING) { // 일단 다시 Accept 걸어준다 RegisterAccept(acceptEvent); } } } 위 코드는 수업 자료를 받아서 전부 빌드 후에 디버그 실행을 할 경우 0x00007FF7DD492613에(GameServer.exe의) 처리되지 않은 예외가 있습니다. 0xC000001D: Illegal Instruction. 위와 같은 컴파일 에러 창이 template <class _Ty2 = _Ty, enable_if_t<!is_array_v<_Ty2>, int> = 0> _NODISCARD _Ty2* operator->() const noexcept { return get(); } memory 파일 안 get() 부분에 나타 납니다. 알아본 결과 session->GetSocket() 함수에서 발생하는데요 shared_ptr 의 화살표 operator 에서 에러가 발생합니다. 환경에 따라 에러가 있고 없고의 차이는 회사와 집입니다.. 집에서 Debug x64 로 하면 에러가 나는데 Debug x86 으로 하면 에러가 안납니다.. 이런 글을 올려도 되는지 모르겠지만 이틀째 답답해서 죽을 맛이에요. 이런 현상을 겪어 보신적 있으신가요?? 해결 방안은 어떻게 되는지 알고 싶습니다...
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
AcceptEx 생성시, IocpEvent 의 개수 문제.
안녕하세요. 루키스님. 강의를 보다 질문이 생겼습니다. Listener::Init( ) 함수에서, acceptCount 를 생성해서, 넣어주고 있는데, 이때 acceptCount 이상의 접속 요청이 발생하게 되면, 어떻게 해결되나요 ??? *** const int32 accpetCount = 1; for (int 32 i = 0; i < acceptCount ; i++ ){ AcceptEvent * acceptEvent = xnew<AcceptEvent>(); _acceptEvents.push_back(acceptEvent); RegisterAccept(acceptEvent); } ***
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
궁금한 점이 있습니다.
강의 초반부에서 Session::Send()를 수정해주셨는데 { WRITE_LOCK; _sendQueue.push(sendBuffer); } if(_sendRegistered.exchange(true) == false) RegisterSend(); 이렇게 작성하면 안되는 것일까요? 별도로 스택 변수를 사용해야 되는 이유가 있는지 궁금합니다. 멀티스레드 개념이 잘 안잡혀서 번거롭게 사소한 것까지 여쭤봐서 죄송합니다..
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
코드재배치 관련 질문입니다
싱글스레드 환경에서는 코드 재배치가 일어나도 결과를 동일 보장해주기 때문에 atomic과 같은 seq_cst 모델을 안써도 되는데, 멀티스레드 환경에서는 코드 재배치가 일어나기 때문에 seq_cst 모델을 써야한다고 이해했는데요. 1. 그럼 멀티스레드 환경에서는 코드 재배치가 일어날 수 있기 때문에 stack 변수 같은 경우는 스레드 별 독립이기 때문에 상관이 없고 모든 공유 변수나 리소스들을 atomic<int> 등으로 seq_cst 모델로 해줘야 하나요? 2. 다른 질문이긴한데 언리얼 엔진 + Part4 C++ IOCP 연동 강의는 언제쯤 출시인지 알 수 있을까요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
ProcessSend 질문이 있습니다.
SendQueue에 대해서 강의 시간에 배운 락 대신 CRITICAL_SECTION을 사용한다고 했을 때 EnterCriticalSection(&lock_send_queue_); if (send_queue_.empty()) { is_register_send_.store(false); } else { RegisterSend(); } LeaveCriticalSection(&lock_send_queue_); 이런 식으로 작성할 수 있을텐데 아래와 같이 EnterCriticalSection(&lock_send_queue_); if (send_queue_.empty()) { LeaveCriticalSection(&lock_send_queue_); is_register_send_.store(false); } else { LeaveCriticalSection(&lock_send_queue_); RegisterSend(); } 이런 식으로 작성하면 동기화에 문제가 될 소지가 있을까요..? Send는 아래와 같이 작성하였습니다. bool Session::Send(SendBufferRef send_buffer) { EnterCriticalSection(&lock_send_queue_); send_queue_.push(send_buffer); LeaveCriticalSection(&lock_send_queue_); if (is_register_send_.exchange(true) == false) { RegisterSend(); } return true; } 혹시 그리고 저희가 만든 락프리 큐를 센드큐로 활용한 예제는 없는지 궁금합니다..
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
system call 질문 드립니다.
cout , sleep 같은 명령이 system call 이고 커널단에서 실행된다고 하셨는데 c#같이 vm위에서 돌아가는 경우도 console.writeline 같은것도 c++과 동일한 system call 인가요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
서버코어단에서 고려해야 하는 부분?
TCP는 데이터 경계가 없어 부분적으로 오는 경우를 고려해준다고 설명해주셨는데 그 외적으로 패킷 분실, 패킷 손상, 도착 순서 등등은 TCP에서 보장해주기 때문에 서버코어단을 만들때 고려해주지 않아도 되는 게 맞을까요??
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
reinterpret_cast질문이있습니다.
template<typename T> BufferWriter& BufferWriter::operator<<(const T& src) { *reinterpret_cast<T*>(&_buffer[_pos]) = src; _pos += sizeof(T); return *this; } reinterpret_cast c++강의에서 아주 강력한 변환 포인터랑 정수사이도 변환이 가능하고.. 다 가능한 변환 느낌이었는데 앞에*를 붙여주는 이유가 궁금합니다. *reinterpret_cast<T*>(&_buffer[_pos]) = src; =========================== T*로 변환하는데 src가 참조라서 *를 한번 더 붙여주신건가요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
StompAllocator의 VirtualFree를 위한 Alloc 시작 주소 계산
페이지들을 region 단위로, 64k 정렬로 시작 주소를 할당해주는 것이 VirtualAlloc()으로 MSDN을 읽었습니다.다만 이 함수에서 페이지 2개 짜리를 해제할 시, 시작주소가 안맞는 것 아닌가 싶어서요.GRANULARITY = 0x10000 = 65536;baseAddress = address - (address % GRANULARITY);를 해야만, 그래뉼리티 기반으로 할당된 시작지번이 정확히 나오는게 아닌건가...용?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
TypeCast의 Conversion 클래스 질문입니다.
안녕하세요 RooKiss 선생님! TypeCast의 Conversion 클래스를 분석하다가 Conversion 클래스의 Test() 함수와 MakeFrom() 함수가 내부에 cout<<"test"<<endl; 식으로 정의를 했는데요. 정의를 하고 cout<<"test"<<endl; 에 브레이크 포인트를 잡고 디버깅을 하니 Test()와 MakeFrom()이 정상적으로 동작하는 듯한데 브레이크 포인트가 잡히질 않네요... 즉, Test()와 MakeFrom() 내부 함수 로직이 동작이 안됐습니다. C++이나 컴파일러 특성 때문인가요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Condition Variable 에서의 lock 문제
안녕하세요 Rookiss 님 좋은 강의 감사합니다. 다름이 아닌 condition variable 에서 producer ( ) 코드 에서 { { unique_lock<mutex> guard(m); q.push(100); } //생략 } 이렇게 unique_lock 을 걸어주게 되고, Consumer 측에서는 { while (true) { unique_lock<mutex> lock(m); // 생략 } } 여기서 궁금한게, thread1(producer) , thread2(consumer) 시, thread1 에서 mutex m 을 unique_lock 으로 잠가주게 되고, thread2 에서 mutex m 을 또 unique_lock 으로 잠가주게 되어, 재귀적으로 lock 이 일어나게 되는데, 왜 오류가 일어나지 않는지 궁금합니다. ps ) unique_lock 으로 인자를 주어, 처음부터 lock을 안걸어줄 수도 있는데, 그냥 mutex m 만 인자로 넘길시 , 바로 생성자에서 lock 을 걸어버린다고 찾아보았습니다. 헌데, 여기서는 재귀 lock 이 일어난것 처럼 보여서, 제가 잘 이해하지 못한 부분이 있는지 여쭤봅니다.
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
StompAllocator 메모리 오버플로우 감지에 대해 질문드립니다
강의와 같이, 자신의 페이지를 넘어선 메모리에 접근하면 "쓰기 엑세스 위반"이라는 에러가 뜨는 상황인데. 이 때 만약, 오버플로우로 접근하는 바로 그 다음 페이지가 "쓰기 권한이 있는" 페이지 였다면 오버플로우를 잡아내지 못하는건가요? 아니면, 엑세스 권한과 상관없이 단순히 페이지 범위를 벗어났기 때문에 에러를 주는 원리인가요?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
상속관계 복사부분 질문이있습니다.
1. // 상속 관계 복사 template<typename U> TSharedPtr(const TSharedPtr<U>& rhs) { Set(sticta_cast<T*>(rhs._ptr)); } 강의에서 TSharedPtr클래스의 상속관계복사부분이 이해가 조금 부족한 것같습니다. 부모 자식관계에서 받아온 값들을 다시 static_cast<T*>로 하면 복사가 정상적으로 되는건가요? 2. 강의에서 wraight = nullptr 이 부분은 실제로 wraight = WraightRef(nullptr); 로 되어있어서 TSharedPtr(T* ptr) { Set(ptr); }이 호출된 후 복사 연산자가 호출된다고 말씀하셨는데 실제 디버깅을 해보니 복사가 아니라 이동쪽으로 브레이크 포인트가 타고있었는데 같은 맥락인건가요 ?
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
언리얼 연동
안녕하세요. 언리얼 포폴을 준비중인데 언리얼 연동강의가 많이 늦어진다고 해서,, 본 강의와 유니티 연동강의를 보면 언리얼에 iocp서버를 연동할 수 있을까요?(유니티 연동 방법과 많이 다른가요?) iocp서버와 언리얼 연동하는 방법을 찾아봐도 나오지 않아서.. 따로 추천해주실 책 있으실까요? 좋은 수업들 감사합니다.
- 미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
흐름 정리해봤는데 한번 확인해주실 수 있나요>?
안녕하세요 루키스강사님 코드 분석을 드디어 끝냇는데 한번 확인해주실수잇나요? 이 흐름이 맞나요?