월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
lock과 send에 관해서
안녕하세요, 이전 질문 글에 비슷한 내용의 질문이 있었는데 조금 다른 부분이 궁금해서 질문글을 올립니다. 1. Send를 할 때 lock을 건다. (현재 _pendingList가 비어있으면, RegisterSend() 호출하고 이게 끝나야 lock이 풀리게된다. ) 2. RegisterSend에서는 SendAsync를 호출하는데 true라면, 1에서 잡은 lock은 바로 풀릴것이다. 그런데 만약 false가 되면 3으로 넘어간다. 3. OnSendCompleted 에서 lock을 걸려고 한다. 👉 이 때 2번에서 SendAsync가 false가 되어 3으로 넘어온 경우라면, 1에서 잡은 lock이 아직 안풀렸을 것 같은 데 잡을 수 있나? 3번의 질문 내용이 궁금합니다. (1번에서 lock을 잡은 상태로 2번을 호출했고, 2에서 SendAsync의 return 값이 false가 되어 3으로 넘어올 때가 궁금합니다.) 제가 비동기 프로그래밍이 익숙하지 않다보니 이해가 부족해서 이런 질문을 올리게 되었습니다.😁 (제가 아직 뒷쪽 강의를 다 듣지 않았는데, 뒤 쪽에 혹시 이런 설명이 나올까요..?) 감사합니다(__) public void Send(byte[] sendBuff) { lock(_lock) { _sendQueue.Enqueue(sendBuff); if (_pendingList.Count == 0) // 대기중인게 하나도 없으니 해라. RegisterSend(); } } void RegisterSend() { // _pendingList가 비어있을 때만 여기로 들어온다. //_pendingList.Clear(); //_sendArgs.SetBuffer(buff, 0, buff.Length); while(_sendQueue.Count > 0) { byte[] buff = _sendQueue.Dequeue(); _pendingList.Add(new ArraySegment<byte>(buff, 0, buff.Length)); } _sendArgs.BufferList = _pendingList; bool pending = _socket.SendAsync(_sendArgs); if (pending == false) { OnSendCompleted(null, _sendArgs); } } void OnSendCompleted(object sender, SocketAsyncEventArgs args) { // 예약한 pendingList 완료됨 lock(_lock) { if (args.BytesTransferred > 0 && args.SocketError == SocketError.Success) { try { _sendArgs.BufferList = null; _pendingList.Clear(); if(_sendQueue.Count > 0) // 보내는동안 누가 또 Queue에 쌓았다. { RegisterSend(); } } catch (Exception e) { Console.WriteLine($"OnSendCompleted Fail {e}"); } } else { Disconnect(); } } }
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Disconnect 함수의 임계영역
안녕하세요 ㅎㅎ 궁금증이 생겨 질문드립니다. 강의 21분에 "Disconnect 함수를 동시 다발적으로 실행하거나 같은 Thread가 두 번 한다면" 이라고 말씀하셨습니다. Q.1 Disconnect 함수를 동시다발적으로 실행할 수 있나요? 다르게 말하면 DisConnect함수가 실행하는 내용이 임계영역인가요? 여러번 고민해봤는데 Disconnect를 호출하는 OnAcceptHandler는 인자로 스레드마다 독립적으로 하나씩 가지고 있는 clientSocket을 받고 clientSocket으로 Session.Start(clientSocket); 을 통해 Session 클래스의 객체를 초기화 해주기에 임계 영역이 아니라고 생각합니다. 후자로 말씀하신 하나의 Thread에서 실수로 코드에 두 번 기입해서 Disconnect를 하지 않는 이상 별다른 문제가 없다고 생각합니다. Q.2 매번 코드를 작성할 때마다 임계영역인지 아닌지 고민하면서 코딩하다 보면 머리가 터질 것 같습니다. 선생님께서는 눈에 보이는 임계영역에만 상호배제를 해주고 후에 배포 전에 테스트 단계에서 문제가 발생하면 그때 수정하는것도 현명한 방법이라고 생각하시나요? 조언 부탁드립니다!!
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
GameRoom에 모아 놓은 작업 Flushed 된 개수가 160개인데 정상인가요?
안녕하세요 예제코드에서는 Flushed 100 item인데 제가 실행했을때는 Flushed 160 item이더라구요 컴퓨터에 따라서 차이가 나는거죠? 제가 코드를 잘못 작성한건지 알고싶어요
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Parallel.Invoke 호출시 메인스레드 사용 이유
안녕하세요 의아한 점이 생겨 질문드립니다. 메인에서 MaxThread의 수를 3개로 지정한 상태에서 Invoke를 호출하고 ManagedThreadId를 확인하면 Invoke시에 메인 스레드인 1번을 사용하는 이유가 무엇인가요?.. MaxThread를 (1,1)로 설정해도 무조건 한 번은 메인 스레드를 사용하고 그 다음부턴 풀에서 스레드를 꺼내쓰더라구요.. 왜 한 번은 메인스레드가 사용되는건가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
메모리 할당관련 질문
안녕하세요 ㅎㅎ 강의를 듣다가 여러 궁금증이 생겨 질문드립니다. Q1. 메모리 할당에 관한 질문입니다. 질문드리기 앞서 무성의한 변수 작성에 사과드립니다. static 변수(a)는 Data영역에 멤버변수(b)는 Heap영역에 멤버함수(Func)는 Code영역에 멤버함수 내에 존재하는 지역변수(c)와 t2는 Stack영역에 할당된다고 알고있습니다. 실제 Main에서 Test라는 클래스를 인스턴스화후에 메모리 구조에 대해서 몇 가지 질문드리고 싶습니다. Test t2 = new Test(); 이 코드를 실행하게 되면 Stack에 t2라는 변수가 생기고 Heap에 할당된 메모리를 가리키고 있을거라 생각합니다. 궁금한건 Func함수입니다. 질문속의 작은 질문들을 정리해서 말씀드리면 Q1.1 t2라는 변수를 통해서 저희는 멤버변수인 b에도 접근하고 Func라는 함수도 호출합니다. 다만 t2는 heap의 주소를 가리키는 포인터인데 heap영역에 있지 않는 Func라는 함수를 어떻게 가리키는건가요? 한 가지 추정을 해보면 heap어딘가에 Func의 Stack 시작점 주소를 저장할 공간이 있고 Stack에 함수가 할당되면 그곳으로 매핑을 시켜주는 건가요? Q1.2 Code영역이 궁금해서 검색하다가 지역변수는 함수 호출시에 Code영역에 저장되는 함수 정의를 활용하여 초기화 된다. 라는 글을 발견했습니다. Code영역에 함수가 정의된다는것과 Stack에 함수가 할당되는게 구체적으로 어떤 연관성이 있는지 이해가 잘 안됩니다.. 정의를 활용한다는게 어떤 의미안가요? Q1.3 클래스 내부에서 Static Test t1 = new Test(); 코드를 실행해봤습니다. static변수는 클래스가 메모리에 올라갈때 할당 된다고 배웠는데 t1이라는 변수가 Data영역에 할당되자마자 Heap에도 데이터가 할당되는건가요? Q1.4 이러한 메모리 할당에 대한 의문이 생기면 실제로 실험해보고 검증하고 싶은데 Stack Heap Data Code 영역을 실제로 확인할 수 있는 방법이 무엇인지 모르겠습니다 ㅠㅠ.. 디버깅처럼 이러한 것들을 확인할 수 있는 방법이 있을까요..?? Q2. ReaderWriterLock에 관한 질문입니다. WriteUnLock 부분에서 Exchange를 사용하지 않고 _flag = EMPTY_Flag;를 해주면 문제가 발생할까요? 제 스스로 고민해본 결과 WriteUnLock은 어쨋든 Lock을 잡은 상태에서만 호출을 한다고 가정했으니 임계영역이 아니라고 생각했습니다. 재귀적으로 호출을 해도 별 문제가 없다고 생각한건 싱글스레드가 독보적으로 호출할 수 있는 영역이니까요. ReadUnLock의 경우는 여러 스레드가 동시에 값을 변경하니 Interlocked.Decrement(ref _flag);를 호출하는게 맞다고 생각하는데 WriteUnLock을 _flag = EMPTY_Flag;이와 같이 작성해도 별 문제가 없을까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Thread와 Context Switch에 대한 질문
안녕하세요 ㅎㅎ강의 잘 듣고 있습니다. Q1. 유저레벨 스레드? 커널레벨 스레드? 선싱님 강의를 수강하니 운영체제 수업에서 배운 내용들이 하나 둘씩 기억나서 매우 반갑네요. 제가 기억하는 내용을 적어보면, 일반적으로 IO나 인터럽트에 의해 발생하는 프로세스 문맥 교환과 매우 유사하게 쓰레드도 레지스터나 캐시의 정보들을 주 메모리로 옮기는 과정을 운영체제가 도맡아 담당하게 됩니다. 때문에 쓰레드간의 문맥 교환시에 Kernel모드로 진입한다고 말씀하신거겠죠. 궁금한점은 쓰레드의 구현 방식에 따라? (아마 유저 레벨 쓰레드와 커널 레벨 쓰레드로 구별하는 것 같습니다.) 문맥 교환의 비용이 차이가 난다고 어디선가 배운 기억이 납니다. 본 강의에서 사용한 쓰레드는 생성시 라이브러리 함수를 사용했고.. 아마 내부적으로 시스템 콜을 호출했고 결과적으로 유저가 아닌 Kernel이 스케쥴링하니 커널레벨 스레드인 것 같은데요.. 그렇다면 유저레벨 스레드라는건 어떤걸까요? 유저(개발자)가 문맥교환을 담당하고 스케쥴링도 담당하는, 모든걸 개발자가 도 맡아하는 스레드인가요? 실제 유저 레벨 스레드가 많이 사용되는 경우는 어떤 경우인가요? Q2. AutoResetEvent는 Kernel단으로 내려가서 문맥교환으로 인해 spinlock보다 성능이 저하될 수 있다고 말씀하셨습니다. 궁금한건 sleep 혹은 yield또한 cpu의 점유권을 포기한 상태에서 다른 스레드를 실행할 수 있기때문에 kernel로 진입후에 문맥교환이 발생하고 이에따른 성능 저하가 일어날 수 있을까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
비동기 함수에 대한 질문
안녕하세요. Rookiss님 아래 질문 보다가 저도 궁금한점이 있어 댓글 남깁니다.ReceiveAsync는 예약이 걸렸을때 별도 Thread가 사용되는게 아니라 Windows 운영체제에서관리해주는것이라 답변해주신거 봤습니다. 첫번째 질문은 비동기 함수들은 전부 ReceiveAsync 처럼 별도 Thread가 아닌 Windows 운영체제에서 관리하는것으로 이해해도 될까요? 두번째로 C++ 네트워크 강의가 있다면 바로 구매해서 참고하고 싶지만.. 아직 제작하시는데 한참 남으신거 같아서 여기에 질문 남깁니다.. C++의 경우 Ioctlsocket()을 사용해서 블러킹 함수들을 논블러킹 함수로 사용할 수 있는걸로 알고 있습니다. 다만, C# Socket처럼 Async 라던가 Begin 같은 비동기 함수를 제공하지 않는데.. 논블러킹 함수로 직접 callback 비동기를 구현해야 하는건가요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Thread의 실행순서를 잘 이해한건지 모르겠어요
처음에 메인에서 t.Start();가 Console.WriteLine("Hello World!")보다 먼저 와 있어서 제 생각에는 먼저 Hello Thread!가 먼저 찍힐 줄 알았는데, 실행해보면 Hello World!가 먼저 찍히고 Hello Thread!가 찍히더군요. 그렇다는건 이 Thread라는 일꾼은 메인이 끝난 뒤에야 실행된다는 건가요??
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
콜백함수 질문 2
삭제된 글입니다
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
뜬금 없는 질문이지만 강사님 비주얼스튜디오 테마를 알수있을까요?
테마가 정말 마음에 드는데 혹시 알수있을까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
게임소스
part3를 듣고 게임을 모작해보려고 하는데요 혹시 모작할 때 필요한 소스들은 어디서 구하는지 대략 좀 알 수 있을까요? 수업 외적인 질문이지만 비전공자라 어디 물어볼데가 없어서 여기다 질문드립니다
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Unity 관련 질문 드립니다!
안녕하세요 강좌를 다 보고 유니티로 움직이는 것을 연동해보고있는데요, 두명의 플레이어가 들어와있을때 자신의 움직임은 부드럽게 움직이지만 (간단하게 translate로 움직이게 해두었습니다) 상대방의 움직임이 부자연스럽게 뚝뚝 끊기며 렌더링되었습니다. 유니티 클라쪽에 상대방 position을 로그로 띄워보기도 하고 서버쪽에서 어떻게 위치값을 받는지 콘솔창에 띄우기도 해보았는데 결론적으로 S_BroadcastMove 나 C_Move 패킷의 위치값은 양쪽에서 잘 쓰고 받고 하는 것 같습니다.. 상대방의 움직임도 부드럽게 렌더링되면 좋겠는데 어떤 부분이 문제인건지 잘 모르겠습니다...!!
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Fuc<Session> _sessionFactory 관련
안녕하세요! sessionFactory 관련 질문드립니다! Listener에서 Accept 후 Session을 만들어주는 부분에서 _sessionFactory를 Func<Session>으로 만드는 이유가 궁금합니다! 단순히 Session _sessionFactory; 로 만들어 Init 할 때 인자를 Session 클래스로 받고 server에서는 만들고자 하는 Session을 람다식이 아닌 new GameSession()으로 만들어도 실행이 되더라구요..! 해당 부분이 추후 어떻게 구체적으로 사용될지는 잘 몰라서 이 부분을 Func로 만들어두는 이유가 궁금합니다..! 더불어 문법적인 질문이지만... Connector에서는 _sessionFactory에 구독할 때 _sessionFactory += sessionFactory 가 아니라 _sessionFactory = sessionFactory로 사용하시던데 사용에는 상관없는 부분일까요??
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
RegisterAccept에서 pending 여부 판단에 대하여
안녕하세요!! pending 관련하여 질문드립니다!! void RegisterAccept에서 굳이 if(pending == false) OnAcceptCompleted(null, args); 를 넣어주는 이유는 무엇인가요?? 설명에서는 정말 쓰레드가 할일이 없어서 바로 처리해줄 상황을 생각해서 넣어주신거라고 하셨는데 이 부분을 없애도 args.Completed 이벤트 발생 시 문제 없이 OnAcceptCompleted 를 불러오던데 굳이 넣어주신건 성능 개선차원인가요??
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Servercore와 DummyClient의 동시실행
안녕하세요! 매번 정성스런 답변 감사드립니다. 조금 뜬금없는 질문일 수 있지만... Server core와 Dummy Client를 동시에 실행시키는 강의의 코딩도 일종의 멀티쓰레드 환경으로 볼 수 있는 건가요..?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
웹서버와 게임서버의 활용에 관하여 질문이 있습니다.
좋은 강의 만들어주셔서 감사합니다. 정말 잘 가르쳐주셔서 너무 익혀나가고 있습니다. 다름이 아니라 혹시 웹서버와 게임서버의 활용에 관하여 질문이 개인적인 질문이 있는데 어디에 문의를 드려야 할지 모르겠어서 여기로 질문드립니다... 친구들과 같이 진행중인 프로젝트가 있는데 서버를 처음 다루다보니 AWS를 활용한 웹서버 + 클라이언트 구조로 활용하여 게임을 개발하려 하였습니다. 그런데 이제 OT에서 웹서버와 게임서버의 활용법을 얘기하셔서 저희 게임의 기획에 맞게 게임서버를 활용하기로 하였습니다. 다만, 웹서버와 게임서버를 병행하여 랭킹시스템, 유저정보 등은 웹서버를 활용하여 매치메이킹을 해주는 등에 활용하고 실제 게임이 매치되어 진행하는 동안에는 게임서버를 사용하는 것으로 구상중에 있습니다. 이제 로딩시 버전체크 등 파일 확인에도 웹 서버를 활용하면 괜찮을거 같아서 이렇게 진행을 하고 싶은데 하나의 게임 안에서 서버를 교체하여 매치를 진행한다는 것이 가능한 것인지가 궁금합니다. 저희가 아직 학생신분을 가진 상태라서 서로가 공부목적으로 진행하는 프로젝트이다 보니 웹서버에 관심을 가지고 있는 친구가 있어 포기할 수는 없는 상태인데 이게 이중연결이 진행이 되는 것인지 아니면 웹서버의 연결을 끊고 게임서버로 다시 연결시켜주는게 괜찮은 방식인가 싶습니다... 강의와는 무관한 질문 정말 죄송합니다 ㅠㅠ
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
음성채팅 UDP
음성채팅도 제가 만드는 프로그램에 넣을 예정인데요. 현재 TCP로 서버를 만들고 잇는데 음성채팅을 만약 UDP로 진행하게 된다면 음성채팅 서버 하나를 더 만들어서 하는게 나은가요 아니면 TCP 서버에서 LISTEN하는 소켓을 하나 더 열어서 한 소켓은 TCP 다른 하나는 UDP 이렇게 하는게 나은가요? 그리고 이런식으로 하나의 서버에서 TCP UDP를 혼용하는게 가능한가요? 또 클라이언트 같은 경우도 소켓을 두 개 만들어서 음성채팅 할 때는 UDP 소켓을 쓰고 다른 것을 할 때는 TCP 소켓을 쓰는게 가능한가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
게임 서버에서 로그인 서버
처럼 소켓 통신이 아닌 http통신을 하는 서버도 지금 만들고 있는 게임 서버 내에서 패킷을 전송하는 식으로 다 처리를 하는게 일반적인가요? 아니면 따로 또 웹서버를 구성하는게 일반적인가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
receiveasync 질문입니다.
제가 이해한 바로는 receiveasync를 쓰게 되면 쓰레드풀에서 쓰레드를 하나 끌어와서 그 안에서 루프를 돌면서 데이터가 오는지 안오는지 체크하다가 온게 확인되면 args.Completed 를 invoke 시켜준다고 이해했는데요. 그럼 만약에 동접 10000명이 있는데 이들이 처음에 소켓에 연결하고 receiveasync 함수를 호출하면 쓰레드가 10000개가 생성되는 것 아닌가요? 그리고 만약 이 10000명이 send를 보내주기 전까지는 각각의 10000개의 쓰레드가 루프 안에서 블락되어 있는 상태 아닌가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
receiveasync나 sendasync나 호출할 때마다
쓰레드풀에서 새로운 쓰레드를 갖고 와서 거기서 데이터를 받거나 보내기까지 기다리고 있는 건가요? 그럼 한 클라이언트한테 동시에 send를 50개 보내는 상황이 생기면 쓰레드가 50개가 생기게 되는 건가요?