월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
단일 스레드로 처리할 경우 속도 문제점 있나요?
GameRoom을 하나의 스레드로 jobqueue를 사용해서 공유자원을 관리 하면 lock에서는 자유롭지만 하나의 스레드인 만큼 많은 처리를 해야할 경우 딜레이가 생길수도 있을거라고 생각하는데 lock을 타이트하게 거는 방법보다 하나의 스레드에서 처리하는게 속도가 더 빠른가요?하나의 스레드로 룸을 관리하니 결국 작업을 하나씩처리에 따른 속도 이슈가 없는지 궁굼합니다. 예를들어 갑자기 수많은 이용자가 들어와 엔터패킷을 탄다면 디비도 접근해야될때 이에 따른 실시간 처리 성능이 보장되는지 궁굽합니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
원자성
안녕하세요.처음 interlocked 없이 for문을 10,000회로 두고number를 ++하거나 --했을 때 0 이 잘 출력됐는데,이 땐 그냥 반복 횟수가 적어서 원자성 문제가 발생되지 않았던 건가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
6:00
릴리즈 모드로 해도 디버그 모드랑 동일하게 출력되는데 뭐가 문제인가요? using System.Threading;namespace ServerCore{ internal class Program { // 전역이기 때문에 쓰레드들이 동시에 접근 가능 static bool _stop = false; static void ThreadMain() { Console.WriteLine("쓰레드 시작!"); while(_stop == false) { // 누군가가 stop 신호를 해주기를 기다린다 } Console.WriteLine("쓰레드 종료!"); } static void Main(string[] args) { // Thread t = new Thread(ThreadMain); Task tt = new Task(ThreadMain); tt.Start(); // 1초 존야 후 다시 실행 Thread.Sleep(1000); _stop = true; Console.WriteLine("stop 호출"); Console.WriteLine("종료 대기중"); tt.Wait(); // t.Join(); 과 동일 Console.WriteLine("종료 성공"); } }
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
ReaderWriterLock은 반드시 재귀적으로 호출되어야 하나요?
만약 한 쓰레드에서 ReadLock과 WriteLock이 전부 호출된다고 했을 때 반드시 호출의 역순으로 Unlock을 호출해야 되나요? 아래는 C#에 구현돼있는 ReaderWriterLockSlim 클래스를 사용하여 실행한 예시입니다.class Program { static ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); static void Main(string[] args) { Task.WaitAll( Task.Run(() => { _lock.EnterWriteLock(); _lock.EnterReadLock(); Thread.Sleep(5000); _lock.ExitWriteLock(); _lock.ExitReadLock(); })); } }WriteLock -> ReadLock -> WriteUnlock -> ReadUnlock 순으로 호출했고 정상적으로 작동합니다.강의에서 구현한 ReaderWriterLock을 사용해도 예외가 발생하지는 않습니다만 위의 순서로 호출하면 flag가 엉망이 됩니다.public void WriteUnlock() { int lockCount = --_writeCount; if (lockCount == 0) Interlocked.Exchange(ref _flag, EMPTY_FLAG); }동일한 쓰레드가 ReadUnlock을 호출하지 않은 상태에서(즉 read count가 0이 아닌 상태에서) WriteUnlock을 호출할 경우 flag가 0으로 초기화되기 때문에 이후에 ReadUnlock을 호출할 경우 flag가 -1로 초기화됩니다. 제가 생각하기엔 굉장히 특이한 케이스고 실제로 함수가 재귀적으로 호출되기 때문에 발생할 일은 없다고 보는데요...혹시라도 휴먼에러로 위와 같은 상황이 벌어질 경우를 대비해서 예외를 추가하거나 WriteUnlock 로직을 수정해서 'EMPTY_FLAG'가 아닌 '_flag & READ_MASK'를 대입하면 어떤가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Mac OS 쓰레드풀 사용 문제 질문드립니다. (11:12)
위쪽에도 같은 맥북 질문이 있는것으로 확인 하였는데 해결방법을 모르겠어서 질문드립니다. 쓰레드가 Console.WriteLine까지는 진입을 하지만 출력이 되지는 않는 문제가 발생합니다.또한 중간에 쓰레드가 전부 사라져버리고 디버깅이 더이상 진행되지 않는 문제가 발생합니다.
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
PacketSession에서 buffer.Count와 dataSize의 비교
안녕하세요 PacketSession에서 if (buffer.Count < dataSize) break;이 부분의 코드가 왜 필요한지에 대해서 의문이 생겨 질물 남깁니다 예를들어 100바이트 크기의 버퍼가 OnRecv매개변수로 들어왔고 해당 100 바이트가 5가지 패킷의 정보를 들고 있다고 했을 때하나의 패킷을 처리할 때 마다 해당 크기의 dataSize만큼 buffer크기(Count)가 갱신 될텐데 그렇게 된다면 위의 조건에는 들어오게 될 일이 전혀 없게 되는거 아닌가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
System.InvalidOperationException 이러한 오류가 나옵니다.
System.InvalidOperationException: 'The ThreadLocal object is not tracking values. To use the Values property, use a ThreadLocal constructor that accepts the trackAllValues parameter and set the parameter to true.' 코드를 작성했는데 이러한 오류가 나옵니다.제가 작성한 코드에 오타를 뒤져봐도 찾을 수가 없습니다.혹시 어떠한 경우에 이런 오류가 생기나요 100% 로 오류가 나옵니다.public static ThreadLocal<SendBuffer> CurrentBuffer = new ThreadLocal<SendBuffer>( () => { return new SendBuffer(ChunkSize); }, trackAllValues: true); 찾아보니 스레드 로컬 커런트 버퍼를 만들 때 이렇게 해주면 오류가 사라지긴 합니다.왜 이런 문제가 발생하는 건가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
소캣 통신 데이터 유실 궁굽합니다!
안녕하십니까. 강의너무잘 듣고있습니다. 서버를 공부하면서 데이터가 유실되면 어떤 방식으로 진행해야하는지 궁굼해서 문의드립니다.tcp/ip특성상 안전성이 높아서 유실이 안되는 걸로 알고있는데 유실될 가능 성도있나요?데이터 유실이된다면 어떻게 처리해야하나요?데이터 유실이 실무에서도 일어나나요?일반적으로 데이터 유실이란게 tcp/ip에서 데이터가 끊어져서 들어오는걸 말하는 건가요? 만약 데이터 유실처리 방법으로 유실 유무를 판단하여 다시 서버에서 요청을 하는 로직을 만든다면 일반적으로 재전송 패킷을 따로만드나요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안전한 게임 개발
안녕하세요. 루키스님의 강의를 듣고 멀티플레이 게임을 만들어보려고 하는데, 어디서부터 어디까지는 서버가 처리하고 나머지는 클라이언트가 처리해야 할지 고민이 됩니다. 서버에 침투할 수 있는 핵을 최대한 막을 수 있는 안전한 상황을 구축하고 싶습니다... 그리고 서버와 클라이언트는 동시에 개발하는 게 좋을까요 아니면 클라이언트를 전부 개발 후 서버를 개발하는 게 좋을까요? 감사합니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
send 와 recv 관련하여 질문이 있습니다!
클라입장에서 Connect를 통해 연결을하고 연결된 소켓에 Send를 하게되면 서버입장에서 Recv하게되는부분에서 1.public void Start(Socket socket){ _socket = socket; _recvArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnRecvCompleted); _recvArgs.SetBuffer(new byte[1024], 0, 1024); _sendArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnSendCompleted); RegisterRecv();}이부분에서 RegisterRecv를 하나만 써 준 것이 낚싯대에 비유하여 접근을 하고있을시 다른쪽에서 접근을 못한다고 하셨는데. 이게 구조적으로 그렇게 짜여진 것인가요??+ 또 RegisterRecv() 이것을 여러게 써주면 lock을 걸어야 하는건가요 ?? 2.그리고 OnSendCompleted 에도 lock을 건 이유가_sendArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnSendCompleted);이 부분에서 중복해서 들어오는 것을 방지하기 위해 거셨다고 하셨습니다. 그럼 Recv의_recvArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnRecvCompleted);이 부분은 어떻게 다른건가요?? 이 부분은 제 나름대로 이해하려고 예를 든 부분입니다. 제대로 이해했는지 봐주시면 감사합니다!Send와 Recv를 게임의 1:1 채팅에 적용하면 A유저와 B 유저가 1:1 채팅을 하고있는 중에 A유저가 채팅을 보내면 클라에서 Send를 하고 서버에서 Recv를 해 받고 그걸 서버 Send를 통해 B유저 클라에 보내준다 (이 부분에서 서버 Send는 1:1하고있는 B에만 가야하니까 lock을 검 : 또 다른 유저(클라)가 보낸 채팅? 들이 섞이지않게... )
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Listener 수업부분 질문입니다!
코드 실행하면 이런식으로 브레이크포인트가 잡히는데 왜 이런거 일까요 .. 밑줄도 많이생기고 해서 질문남깁니다!
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
EventHandler<T> 를 사용하는 이유가 무엇인가요?
Listener 클래스에 args.Completed += new EventHandler<SocketAsyncEventArgs>(OnAcceptCompleted); 부분을 args.Completed += OnAcceptCompleted; 이렇게 바꾸어도 문제가 생기지 않는데 왜 EventHandler<T> 를 사용하는 것인가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
RecvBuffer 질문
안녕하세요. Session에서 _recvArgs.SetBuffer() 하는 부분에서 궁금증이 생겼습니다. _recvBuffer.WriteSegment는 다음에 올 패킷 사이즈가 어느 정도인지 모르니버퍼의 offset + writePos부터 여유공간 끝까지(FreeSize)를 뭉탱이로 가리켜서 주는걸로 이해했습니다.그리고 _recvArgs는 WriteSegment가 가리키는 공간을 자신의 버퍼로 사용합니다. 만약, 실제로 보내고자 했던 패킷의 사이즈가 10인데, _recvArgs의 FreeSize가 5라면,소켓은 일단 5만큼만 버퍼에 넣은 다음에 버리고, 나머지 5만큼의 재전송을 요청하는 건가요?아니면 아예 버리고 재전송을 요청하는건가요?그것도 아니라면 물밑(하위 레이어)에서 버퍼가 꽉 찼다는 신호를 서로 주고받아서 혼잡(?)이라 판단하고 애초에 보내지 않고 기다리는건가요? (버퍼가 비어지길 기다리다가 지치면 Disconnect 혹은 Loss?) 그리고 RecvBuffer의 Buffer가TCP 이론을 배울 때 말하는 window size와 직접적으로 연관되는 건가요?아니면 소켓 별도의 버퍼가 또 따로 있는건가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Unity 연동 시 Disconnect 문제
안녕하세요 강사님코드비교도 하고 소스코드를 다운 받아서 시도를 해도 해결이 되지 않아 문의 드립니다.유니티 2022.3.15f 버전을 사용하고 net8.0을 이용하여 서버 및 클라이언트 빌드를 했습니다.유니티 연동까지 했고, 버퍼크기는 65535로 설정해두었습니다.유니티 connector.cs에서 클라이언트를 1로 설정했을 때에는 문제가 없으나2 이상 올릴 경우 1번이 무조건 disconnect 처리가 됩니다. 100이상 올릴 경우 중간에 패킷조립에 실패하여서버가 종료됩니다. 며칠을 고민하고 코드를 비교하고 강사님의 코드로만 진행을 해도 똑같아 문의남깁니다.
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Connector 강의에서 에러가 뜹니다..
모듈이나 라이브러리를 빌드하고 있으면 /main을 지정할 수 없습니다. 라고 에러가 뜨고 있습니다. vs2022 버전으로 사용하고 있구요. DummyClient랑 Server 모두 참조 프로젝트로 ServerCore를 걸어주었습니다. 위가 ServerCore의 속성이구요. 이게 Server의 속성입니다.DummyClient도 똑같아요. 어디가 문제인걸까요 ?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Console.Writeline 메모리누수
JobTimer 까지 모두 수강하고 Session쪽 코드에서 RecvBuffer _recvBuffer = new RecvBuffer(1024); 이것만 이렇게 다시 수정했습니다. 그리고 실행시켰는데 메모리가 늘어나더니 저런 오류가 떠서 Console.Writeline 쪽 코드를 지우고 실행시키니까이렇게 메모리가 계속 늘어나지 않고 일정하게 유지 되는데 단순히 Console.Writeline이 많이 실행돼서 그런건가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
AcceptAsync() 와 BeginAccept() 의 차이가 궁금합니다.
이 강의를 구매하기 전 이런저런 자료를 찾아보며 혼자 TCP 통신을 공부하고 있었습니다. 그런데 제가 공부할 때는 Begin~() 를 사용했었습니다. 그런데 이 강의 에서는 ~Async() 를 사용하더라고요 사용하기는 Begin~() 이 더 간단하던데 이 강의에서 ~Async() 를 사용하는 다른 이유가 있을까요? 궁금합니다.
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
질문 있습니다
영상에서 7분즘에 이런 말씀을 하셨는데요."커넥터를 딱 하나만 하는 경우도 있겠지만 경우에 따라서는 우리가 리스너에서 계속 뺑뺑이를 돌면서 천명이건 만명이건 계속 받을 수 있는 것처럼 커넥터도 한 번만 받고 끝내는게 아니라 여러 병을 받을 수 있으니까 굳이 이런 식으로 소켓으로 받기 보다는 이런 식으로 이벤트를 통해서 인자를 넘겨주고 있는 것이다."하지만 그 리스너에서는 Socket을 필드로 들고 있도록 하셨었잖아요? Socket을 필드로 들고 있는 것과 SocketAsyncEventArgs의 Token으로 socket을 넘겨주는건 결국 똑같이 작동하는 건가요?connector에서는 Socket을 필드로 두지 않고 args의 token으로 socket을 건네주신 이유를 이해하지 못하겠습니다.아니면 그냥 똑같이 동작하는데 이런 방법도 있다고 알려주기 위함이셨나요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
GameRoom.Flush() 수행 중에 _sessions가 변경 되면, 컬렉션 변경 에러가 나옵니다.
// GameRoom.cs public void Flush() { foreach (ClientSession s in _sessions) s.Send(_pendingList); _pendingList.Clear(); }foreach를 돌며 s.Send()를 하는 와중에_sessions가 변경되면,(_sessions.Add 되거나 _sessions.Remove 되면)아래와 같이 컬렉션 변경 에러가 나옵니다. 이를 해결하려고 아래와 같이 _sessions를_sessionsCopy에 복사하여 foreach 돌렸습니다.// GameRoom.cs public void Flush() { List<ClientSession> _sessionsCopy = _sessions.ToList(); // 복사 foreach (ClientSession s in _sessionsCopy) s.Send(_pendingList); _pendingList.Clear(); _sessionsCopy = null; } 더 좋은 방법이 있을까요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
명시적으로 함수를 호출하지 않으면 무조건 스레드 세이프할까요?
안녕하세요? 강의 재밌게 보고 있습니다.아래 인프런 질문을 보면Q. Receive()는 lock을 사용하지 않는 이유?A. 명시적으로 Recv()처럼 호출하지 않기 때문에 1번에 1개의 스레드만 접근하여 스레드 세이프함이라는 질문을 보았는데요, 이 답변을 조금 확대 해석해 봤는데Q. 명시적으로 함수()를 하지 않으면 무조건 스레드세이프할까요? 답변 미리 감사합니다.