월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
ClientSession의 Room이 null인 경우
안녕하세요.Part 4를 완강하고 Part 7으로 넘어가기 위해새로운 솔루션을 생성해서 기존 Part 4 솔루션 내의프로젝트들을 우선 Ctrl + C, V 한 뒤 기존 프로젝트 추가로Part 7에서 사용할 서버 솔루션을 Part 4와 동일하게 맞추는 작업을 하고 있었습니다!그런데, DummyClient의 연결 수를 20개 정도로 하면 문제가 없지만, 30개부터는 특정 ClientSession의 Room이 null인 상태에서 서버 측의 C_MoveHandler가 실행되어 서버가 뻗어버리는 경우가 간헐적으로 발생하고 있습니다.(강의 보면서 따라 한 솔루션은 100이면 100 잘 되며, 새롭게 복사한 솔루션은 대부분 잘 되지만 가끔식 위 오류가 발생합니다..) 처음엔 단순히 Ctrl+C , V 하는 과정에서프로젝트나 솔루션의 설정값들이 새로운 경로로 옮기면서 동기화가 안되어 생기는 문제인 줄 알았는데,코드를 계속 천천히 읽다보니 의문이 들게 되었습니다. public GameRoom? Room { get; set; }public override void OnConnected(EndPoint? endPoint) {Console.WriteLine($"OnConnected: {endPoint}");Program.Room.Push(() => Program.Room.Enter(this));}제가 이해한 바로는ClientSession의 Room은Listener에 의해서 ClientSession.OnConnected가 호출되며 Program.Room에게 Enter(this)를 요청하고,이후 Program.Room은 Flush()를 통해 특정할 수 없는 시점에 비로소 Enter를 호출하게 되며, ClientSession.Room이 자기 자신을 가리키도록 합니다. 그런데, 정말 운이 안 좋다면 Program.Room이 A번 ClientSession에 대한 Enter 작업이 미처 다 수행되기 전에DummyClient 측의 SendForEach로 인해 A번 ClientSession과 대응되는 ServerSession으로 이동 패킷을 보내고,최종적으로 A번 ClientSession의 Room이 null인 상태에서 C_MoveHandler를 실행 할 여지가 있는 것이 아닌가 생각하게 되었습니다. 혹시 제가 생각하고 있는 것이 맞는건지,아니면 단순하게 솔루션을 잘못 복사해와서 문제가 생긴건지궁금합니다..만약 그런 여지가 있다면 단순히 room이 아직 null인지 체크하고 이동 패킷을 무시하면 되는걸까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
[8:15] GetBytes, GetByteCount 문자열 파싱 질문입니다.
안녕하세요 강사님! GetBytes로 문자열을 파싱하는 과정에서 질문이 있습니다.위의 이미지를 보면 GetBytes 후 Length를 가져와도 8바이트가 나오는데 바이트를 먼저 가져온 후 Length를 가져오면 안 되는 것인가요? 길이를 파싱하는 부분을 제거하여 돌려 보았는데 결과는 잘 나오는 것 같았습니다.여러 번 강의를 돌려봤지만 '몇 바이트가 와야 조립이 되는지 확인하기 위해 두 단계로 나눈 것'이라고 들었습니다. 이 순서가 반대가 되면 조립 가능성 확인을 못하게 되는 것이 이해가 안 가서 질문 드립니다.감사합니다.
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요! UDP 관련 질문입니다!
안녕하세요, 강사님!프로젝트를 진행하던 중 UDP 통신이 필요할지 고려해야 되는 부분이 있다고 생각되어 질문해봅니다 ㅎ..강의에서 사용된 코드에서 Listener와 Connector부분에서 매개변수로 넘겨지는 ProtocolType부분을 Tcp에서 Udp로 변경하면 UDP 통신이 수행되는 건가요??
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
PriorityQueue 관련 질문
안녕하세요.PriorityQueue를 직접 구현 하셨는데,혹시 .NET 6부터 제공하기 시작한 PriorityQueue<TElement, TPriority>를 사용해도 괜찮은지 궁금하여 질문 드립니다! class JobTimer { PriorityQueue<Action, int> pq = new(); object _lock = new(); public static JobTimer Instance { get; } = new(); public void Push(Action action, int tickAfter = 0) { lock (_lock) { pq.Enqueue(action, Environment.TickCount + tickAfter); } } public void Flush() { while (true) { int now = Environment.TickCount; Action? action = null; lock (_lock) { if (pq.Count == 0) break; pq.TryPeek(out action, out var execTick); if(execTick > now) break; pq.Dequeue(); } if(action != null) action.Invoke(); } } }
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
lock()과 InterLocked를 사용한 락 구현에서 원자성 보장의 차이
데드락 강의에서"Lock을 통해 원자성을 구현하는 것인가요?"라는 질문에 아래처럼 답변하신 글을 보았습니다.Lock은 말 그대로 신호등처럼 순차적으로 접근하기 위한 도구이지.어떤 연산이 원자적으로 이루어진다는 보장을 하는 것은 아닙니다. 이번 강의에서는한가지 더 궁금한게, 의사코드로 설명해주실때, 이게 3줄이라서 이 사이에 끼어든거다라는 늬앙스로 처음에는 이해를 했거든요. 그런데 지금 설명을 들어보니까 몇줄이건 관계없이 CPU에서 locked계열 명령어가 적용되면 해당 부분은 원자성이 보장되는건가요?라는 질문에는 그렇습니다. 말 그대로 특수한 명령어이죠. 라고하신걸 보고 헷갈려서 질문 드립니다. Q. 데드락 강의 실습처럼 제가 직접 lock()으로 임계 영역을 감싸서 구현하는 것은 해당 영역의 연산들이 원자적으로 이루어진다는 것을 보장받을 수 없고Interlocked 클래스 같이 마련된 것을 사용하여 임계 영역을 관리하면 해당 영역의 연산들은 원자성이 보장되는 것인가요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
제가 이해한게 맞을까요?
bool repeat = ThreadName.IsValueCreated; 얘는 그냥 Value가 세팅되어 있는지 아닌지를 true false로 반환해줄 뿐이죠? 생성자로 ThreadLocal<T>의 T를 return해주는 람다를 넣어주면 Value를 return한 값으로 채워주고만약에 이미 채워져 있다면 그냥 재사용하는건가요? 생성자로 저렇게 Value를 리턴해주도록 만들어놓으면나중에 Value를 읽어올 때 자동으로 채워주는 건가요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
질문 있습니다
락이 걸려있으면 다른 직원한테 부탁해서 대리로 줄서달라는 느낌이군요그런데 이 다른 직원이 사실은 식당 관리자쪽의 직원이었다라고 하셨는데다른 직원을 윈도우즈 커널 쪽에 있는 스레드라고 생각하면 될까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
컨텍스트 스위칭 질문 있습니다.
bool repeat = ThreaadName.IsValueCreated; if(repeat) Console.WriteLine(ThreadName.Value + " (repeat)"); else Console.WriteLine(ThreadName.Value); 위 코드에서 else 블록에 진입 후, Console.WriteLine이 호출되기 전, 컨텍스트 스위칭이 발생한다면 동일한 스레드에 의해 else 구문이 여러번 호출될 가능성이 있을까요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
6:40초에 하신 말씀에 대해서 궁금한게 있습니다.
쓰레드가 자신의 소유권을 포기한다는 말씀은쓰레드를 조종하는 CPU 코어가 연결을 끊었다라고 이해해도 될까요?그리고 임의의 시간 후에 락이 풀렸는지는 다시 똑같은 쓰레드로 확인하는건가요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
제가 이해한게 맞는지 모르겠습니다.
전역 변수에 값을 변경할 때 쓰레드가 우선 개인 수첩에 적어두고나중에 다른 것들까지 한번에 모아서 최종적으로 메인 메모리에 변경된 값을 기입 한다고 이해하면 될까요? 쓰레드의 개인 수첩이 그 쓰레드를 조종하는 CPU 코어의 캐시가 되는건가요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
패킷 암호화 작업은 강의에 없나요?
패킷 암호화 작업은 강의에 없나요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
클라이언트에서 데이터 변조 할 경우
패킷 id가 변조될 경우의 대응은 없는 상태인가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
args.BytesTransferred가 0인 이유가 뭘까요
강의 잘 보고 있습니다. 하나하나 다 따라해봤는데 전 강의 까지는 문제가 없었지만이상하게 이번강의 따라해보니 유니티와 서버의 연결은 잘된듯 한데 유저가 2명 이상이면 Disconnect를 호출하더군요 이유를 찾아보니까 OnRecvCompleted에서 첫 if문에 있는 args.BytesTransferred 가 계속 0인데 이는 서버측이든 클라측이든 0으로 되어있었습니다. 혹시 코드가 잘못된지 확인해봐도 모르겠어서 강사님께서 올려주신 코드로 서버와 클라를 연결 시켜봐도 똑같이 BytesTransferred가 0이어서 문제가 생기는데 왜 이러는지 알 수 있을까요?? 기기에 따라 다른가요
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
소켓과 세션에 대해 질문 드립니다.
안녕하세요 루키스님!강의 잘 듣고 있습니다. 세션과 소켓의 관계에 대해 궁금한게 생겼습니다.비유로 인해 오해가 생길까 지웠습니다.Connector를 쓰기 전 까지는 더미 클라이언트에 세션을 쓰지 않아 서버와 클라이언트가 서버에서 발급한 세션을 통해 정보를 공유한다고 생각했습니다.마치 실 전화기 처럼 말이죠.클라 (소켓) ---------------세션--------------(소켓) 서버 근데, 커넥터라는 개념이 들어오고 다시 흐름을 살펴보니 서버도 서버의 세션을 사용하고, 클라도 클라의 세션을 사용하니 위의 비유와는 잘 맞지 않아 다시 생각해봤는데 이해한 바가 맞는지 봐주셨으면 합니다.소켓 : 유심칩세션 : 스마트폰(abstract 를 구현해서 어떻게 행동할지 정의했기 때문에 클라는 클라 전용 스마트폰, 서버는 서버 전용 스마트 폰을 가지고 있다.) 클라 (소켓 + 세션) ------------------- 서버(소켓 + 세션)
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
MakePacket<T> 함수 질문있습니다.
PacketManager에서 MakePacket<T>가 호출되면 T 객체를 생성해서 처리하는데, 혹시 해당 함수가 호출될때마다 객체를 생성하는게 아니라 Dictionary에 Register함수로 등록할 때 객체를 생성해서 Dictionary에 등록해주고 그 객체 하나로만 버퍼를 받아서 처리하면 문제가 발생하나요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Completed가 자동 콜백 해줄텐데 왜 직접적으로 또 호출하나요?
public void Init(IPEndPoint endPoint, Action<Socket> OnAcceptHandler){_acceptHandler += OnAcceptHandler;_listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);_listenSocket.Bind(endPoint);_listenSocket.Listen(10);SocketAsyncEventArgs e = new SocketAsyncEventArgs();e.Completed += new EventHandler<SocketAsyncEventArgs>(OnAcceptCompleted);RegisterAccept(e);}void RegisterAccept(SocketAsyncEventArgs e){e.AcceptSocket = null;bool pending = _listenSocket.AcceptAsync(e);if (pending == false)OnAcceptCompleted(null, e);} 이 코드에서 RegisterAccept안에 pending이 false일 때 OnAcceptCompleted를 호출하는 코드를 보여주셨는데 이미 SocketAsyncEventArgs.Completed에 콜백 함수 넣어줘서 자동 처리 되는거 아닌가요?? 실제로 저렇게 함수를 재호출해주는 코드를 빼봐도 정상 작동되는것 같았습니다. 이중으로 함수 호출하시는 이유가 뭔지 궁금합니다!
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
비트 마스크를 사용하는 이유가 무엇인가요?
안녕하세요.강의 정말 잘 듣고 있습니다.처음에는 단순 게임 서버를 구현하는 강의라고 생각했는데, 이론으로만 보던 CS, 네트워크 지식을 직접 구현해보면서 하니 기본기 다지는데 정말 도움이 되네요.그리고 꽤나 자바와 같은 모던 언어를 사용하다보니 깊게 생각하지 않던 부분도 고민할 수 있는 최고의 강의인것 같습니다. 질문으로 돌아가서비트 마스크를 사용하는 이유가 C# 에서 원자적 연산을 제공하는 Interlocked 클래스 함수의 파라미터 때문인가요?처음에는 writer, reader를 체크할 수 있는 클래스 변수를 따로 만들면 되지 않을까? 라고 생각했는데 그렇게 되면 if, if 이런 조건문이 계속 들어가서 원자적 연산이 어려워 져서 그런가요?(별도로 락이나 모니터로 잡을 수 있지만 가독성 측면에서도 그렇고, Interlocked가 표준화 되어 있기 때문에 저렇게 사용하나? 추측합니다.)몇개의 질문을 살펴보니 비트마스크와 Interlocked의 CompareExchange의 조합이 강력하네요. 지금 강의는 언어 레벨에서 지원하는 읽기 쓰기 락 동작 원리를 보여주신 것인데 실제 프로덕션 코드에서 사용하려면 락 타임아웃 같은것도 구현해야하나요?생각해보면 어떠한 경우에 읽기 락이 많이 쌓이고 해제하지 못한 경우일 때 쓰기락에 대기시간이 길어지니 일정 시간 후 락 해소를 시켜줘야 하나 궁금하네요.
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
왜 SendBuffer 를 Session 이 가지면 성능에 문제가 되나요?
1명의 움직임을 100명에게 패킷으로 보내려면 Session 이 가진 버퍼를 100명에게 보내면 될 것 같아서...왜 위 경우에 하나만 만들어서 100명에게 보낼 수 없는지 궁금합니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 재귀허용 WriteUnlock() 질문드립니다!
public void WriteUnlock(){int lockCount = --_writeCount;if (lockCount == 0)Interlocked.Exchange(ref _flag, EMPTY_FLAG);}위의 코드에서 lockCount 지역변수를 만들어주신 이유가 따로 있으신지 궁금합니다! writeCount는 어차피 WriteLock을 잡은 애만 쓰는 변수라고 이해했는데, 그러면 writeCount-=1; if(writeCount==0) 이렇게 써도 괜찮지 않을까라는 생각이 들었습니다!너무 사소한 질문인 것 같은데, 열심히 듣다가 궁금해져서 질문드립니다ㅠㅠ
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
아래 질문 확인 한번 부탁드립니다!
루키스님 안녕하세요? 지난 질문 답변을 아직 못받아서 재질문 드리게 되었습니다. 인프런 AI가 답변을 남겨서 일까요?아님 제 질문에 실수가 있었을까요?후자의 경우라면 좀 더 신경쓸 수 있도록 하겠습니다 https://www.inflearn.com/questions/1126711/%EC%9E%A1%ED%81%901-2%EB%A5%BC-%EB%93%A4%EC%9C%BC%EB%A9%B0-%EC%A7%88%EB%AC%B8%EC%9D%B4-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4-push-%ED%81%90%EB%A1%9C%EC%A7%81-send-%EC%9D%98-%EC%8B%9C%EA%B0%84%EB%B3%B5%EC%9E%A1%EB%8F%84-%EA%B4%80%EB%A0%A8