월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
서버-클라 게임로직 처리에 관해 질문 드립니다
안녕하세요, 항상 양질의 강의 감사히 듣고 있는 대학생입니다!본 강의와 다른 자료들과 병행하면서 학습하다 한가지 궁금한게 생겨서 질문 드립니다본 강의에선 자세히 언급되지 않는 내용이긴 하지만 달리 여쭤볼 분이 없어서 정말 죄송한 마음 가지고 질문드립니다 ㅠㅠ 패킷 전송 지연 시간 때문에 클라이언트에서 서버틱보다 더 나중의 틱을 미리 연산해 화면에 띄우고 있다가, 서버에서 연산한 결과와 다르면 클라이언트에서 앞선 결과들을 수정해 수정된 결과를 다시 띄우는 형태로 돌아가는 게임들이 있다고 알고 있습니다. 또 이럴 경우엔 게임로직 연산을 클라랑 서버 양쪽 모두에서 실행해야 하는 걸로 이해하고 있습니다. 그렇다면 동일한 게임 로직 코드가 클라쪽과 서버쪽 모두에서 실행되게 될텐데 이걸 현업에선 어떤 식으로 처리하는지 궁금합니다! 클라랑 서버측 프로그램에 똑같은 게임로직 코드를 복붙하는 방식으로는 유지보수가 어려울테니 절대 그렇게 할 것 같진 않은데, 그러면 게임 로직 전체를 하나의 함수로 만들어서 서버와 클라 각각 해당 함수를 가져오는 방식으로 처리하나요? 아니라면 어떤 식으로 처리하는지 궁금합니다!
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
send와 lock
안녕하세요 강의 수강중 궁금증이 생겨서 질문 올립니다. 제가 제대로 이해한것이 맞다면 _sendBuff에 enqueue를 하는 부분 자체에 lock이 걸려있고 그 안에 RegisterSend가 실행되는 조건인 _pendingList에 add가 되는 유일한 조건이 RegisterSend인 상태인데 이러한 상황에서 SendQueue에 접근할 때 "다른 프로세스에서 미리 접근만 하고 아직 registerSend를 하지 않는 상황"이 존재할 수 있는지요 sendQueue에 접근 -> SendAsync 이라는 큰 틀 사이사이에 멀티쓰레드를 고려한 여러가지 안전장치들이 모두 시작점의 lcok에 걸려있어서 그 의미가 없어지는것이 아닌가 하는 생각이 듭니다. 감사합니다
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
23분 질문
InterLocked질문입니다. 33번째 줄처럼 InterLocked.Exchange를 해주어 인자로 ref _disconnected 값을 가져오는데 _disconnected 의 주소값을 가져외서 Exchange를 해주는 것이니까 _disconnected 가 0일경우 1로 바꿔주는데 1일 경우는 retunr을 하는 것까지는 이해했습니다. 그런데 두번째로 사용하려고 하면 _disconnected 가 계속 1인 상태이니까 어디선가는 0으로 초기화를 해주어야 다음 클라 세션이 연결을 끊을때 끊을 수 잇는것 아닌가요..?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
세션 생성
안녕하세요.강의를 들으면서 몇가지 의문점이 생겨서 질문드립니다.일단 서버 하나가 존재하고 수백개의 클라이언트가 해당 서버로 연결을 했다면 서버에서 비동기식으로 Lisiten을 하고 있다가 AcceptComplete이 되면 Session new를 하면서 100개가 만들어지는건가요?? 만약 그렇다면 쓰레드 엄청 많이 생성되고 각각 Recving을 하고 있는건가요?? 아니면_listenSocket.AcceptAsync(args) 라는게 실행되면 메인쓰레드는 While문으로 빠져있게 되고 딱 하나의 쓰레드만 거기서 체크하고 있는건가요??..
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
17:54초에 중단점 거는 부분 프로그램 흐름이 잘 이해가 안되서 질문올려봅니다...
다음으로 넘어가면 왜 Session의 OnRecvCompleted의 catch쪽으로 가는지 잘 모르겠습니다 ㅜㅜ (어디를 타고 어디를 탓는지 정확히 이해가 안가네요 ㅠ...) 이런 복잡한 흐름을 어떻게 타고가는지 노하우같은거라도 알려주시면 감사하겠습니다!!
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
모바일에서 네트워크 대전 게임을 만들고 싶은데, 지금 이어지는 강좌로 가능할까요?
강의 복습겸 실습으로 해볼 예정인데, 모바일 게임용으로 따로 준비해야할게 있을까요? 생각 중인 게임은 팔라독 형식의 PVP 게임입니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
WriteUnlock 질문이 있습니다
24분 10초경에 int lockCount = --_writeCount; << 를 두개의 쓰레드가 동시에 unlock하게 되어서 lockCount 값이 0을 갖지 못하고, _flag가 EMPTY_FLAG로 영영 못바뀌는 경우는 없는걸까요??
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Interlocked를 통한 원자성 보장
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 멀티스레딩에 관해서 큰줄기를 잡아가는 중입니다 멀티 스레딩의 기본적인 개념과 쓰임새는 이해를 했습니다. 멀티 스레딩을 사용할 경우에 겪을 수 있는 오류, 즉 다수의 스레드의 경합에 의해서 데드락에 걸리는 경우도 이해를 했습니다. 거기다, 해당 오류에 대한 해결책이 경합시 원자성을 바탕으로, 목표 프로세스는 하나의 스레드에 의해 처리되고 나머지 스레드는 대기하게 만드는 거라고 이해했습니다. (혹시 제가 잘 못 이해한거라면 고쳐주세요!) 원자성을 보장하는 방법에 관해서 제 예상과 강의가 조금 달라서요 강의 초반에 해주신 설명과, 의사코드로 보여주신거로 봐서 처음에는 이 원자성을 보장하는 방법도 C#코드로 구현이 될 거라고 생각했는데, C#에서 마련된 InterLocked 클래스를 쓰시더라고요 거기다 의사코드로 설명하실 때, 이건 이렇게 몇줄로 나눠진 거라서, 화장실에 동시에 2명이 들어가는 가능성이 있다라고 하셨는데 InterLocked를 쓰니까 같은 내용인데 해당 오류가 방지되는걸 보고서 다음과 같은 생각이 들더라고요 원자성은 다른 스레드가 침범할 수 없는 하나의 막을 두루는 것이며 InterLocked클래스가 바로 이 보호막을 둘러달라고 C#에 마련되어 있는 CPU에게 요청하는 방법이 아닌가 싶습니다. 혹시 제가 이해를 똑바로 한 걸까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
다시 돌아왔습니다
강사님 안녕하세요 이전에 이 강의 듣다가 서버 클라쪽은 어려워서 잠시 그만뒀다가 다시 시작을 하려고 하는데요 하는김에 복습도 할 겸, 파트3도 다시 들어야하나 고민중입니다 그러니까, 파트1, 2 는 이어지지 않는 다는 건 알겠는데요 만들어두신 유니티 강의 끝까지 진행하려면, 파트3에서 만든 게임을 끝까지 들고 가야하나요? 아니면 파트4부터 시작해도 되나요?
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
RecvBuffer
안녕하세요, 진도 열심히 빼다가 버퍼랑 패킷 부분에서 막혀서 다시 복습중입니다.이 부분을 잘못 이해하고 있는거 같습니다. RecvBuff _recvBuff = new RecvBuff(1024); // 코드들 중략 void RegisterRecv() { _recvBuff.Clean(); // 질문1. 여기서 segment에 들어오는 값은 WriteSegment가 새로 할당한 값복사가 맞나요 ? //( 호출 당시 멤버변수 _recvBuff 값은 가지고 있지만 원본과 상관없는 ) // 그렇게 생각한 이유 : ArraySement가 구조체이고 new를 했기때문에 ArraySegment<byte> segment = _recvBuff.WriteSegment; // 질문2. MSDN을 읽어보니 SetBuffer 특정 메모리를 참조한다고 쓰여져 있는데요.. 그 // 그러면 여기서 참조하는 메모리가 이 안에 지역변수로 선언된 segment를 의미하나요 ? 즉 지역변수 메모리 주소를 가르키나요 ? // 생각한이유, MSDN SetBuffer설명 : 비동기 소켓 메서드를 사용하여 버퍼로 사용할 메모리 영역을 설정합니다. _recvArgs.SetBuffer(segment.Array, segment.Offset, segment.Count); bool pending = _socket.ReceiveAsync(_recvArgs); if (pending == false) OnRecvCompletetd(null, _recvArgs); } // 세션 코드 끝, RecvBuff 코드 // 코드 중략 public ArraySegment<byte> WriteSegment { get { return new ArraySegment<byte>(_buffer.Array, _buffer.Offset + _writePos, FreeSize); } } 코드 안에 주석으로 질문1, 질문2를 써놨습니다 !!! 따라서 만약에 질문 1, 2가 둘다 예라면 pending이 true나 false이든 함수를 나가면Setbuffer가 참조하던 지역변수 segment는 없어지는 것 아닌가요 ..?비동기가 완료되었을 때 어떻게 _recvBuff 안으로 값이 들어가는지 이해가 안되는거 같습니다 ㅠㅠ.+) 추가적으로 이런 환경에서 디버그 팁이 있을까요 ?코드흐름 좀 보고싶은데 비동기에 2개씩 실행되고 하니깐 단순히 메인부터 F11로 따라가는 것으로는 잘 안보이네요..
- 해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Listner 구현 관련
// 그렇지만 pending true인 경우, 즉 지연 된 경우 // AcceptAsync가 완료 되었을 때(클라이언트 소켓이 들어왔을 때) 우리에게 무엇을 보내주도록 맞춰주어야한다. SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.Completed += new EventHandler<SocketAsyncEventArgs>(OnAcceptCompleted); RegisterAccept(args); 안녕하세요, Listener 강의 12분 40초 쯤에서1. " AcceptAsync가 완료 되었을 때 우리에게 무엇을 보내주도록 맞춰주어야한다. " 라고 말씀하셨는데요.여기서 완료가 의미하는 것이 클라이언트 소켓이 들어올때 말씀하신거 맞나요 ?2. 그래서 pending이 true면 RegisterAccept()는 호출이 끝나서 메인쓰레드로 들어가고메인쓰레드는 무한루프로 돌다가 AcceptAsync가 완료되어 이벤트가 호출되면또다른 작업스레드가 켜지면서 이벤트 핸들러에 등록된 함수를 처리하고 작업쓰레드와 메인쓰레드(while문 무한루프)가 번갈아가면서 실행된다.맞을까요 ?3. 제 생각이 맞다면 새로운 작업 쓰레드와 메인쓰레드는 번갈아가면서 실행될텐데 메인쓰레드에서 이벤트가 발생될 때 새로운 작업 쓰레드가 끝나길 기다리는 Join 함수 같은 것은 따로 없나요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
실행 에러..
에러 발생 이유를 모르겠습니다.. 해결방안을 알 수 있을까요?
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
유니티 강좌 너무 재밌읍니다...
대학교 조별 과제로 C++ 소켓 프로그래밍으로 회원가입 가능한, 카카오톡 형태의 채팅 프로그램 만든적 있는데, 이번 파트를 따라 공부하면서 정말 아쉬운 점이 많았다는 걸 느낍니다. 그때 조별과제가 늘 그렇듯 도와주는 사람 없이 서버랑 클라를 저 혼자 만들었는데, 이걸 봤으면 좀 더 멋있게 만들지 않았을까 싶네요. 스파게티 코드라고 하나요? 나름 열심히 했지만 제 끔찍한 결과물을 생각하면 눈물만 납니다. 이걸 어떻게 해야 할지 어디 물어볼 사람도 없고.. 힘들었는데 그 답이 여기에 있었네요. 보니까 다음 파트에 DB 강좌도 있던데, 채팅 프로그램에서 회원 관리용으로 mysql 사용한 경험이 도움이 될까요. 그리고 앞으로 공부에 꼭 필요한 강좌일까요? 가난한 3학년 대학생이다 보니 모든 강좌를 한 번에 구매할 여력이 없습니다. 그래서 당장 필요하다 싶은 것만 구매하고 있는데... 강좌 듣다보니까 하나도 빠지면 안 될 것 같다는 생각이 듭니다. 원래는 C++ 다렉 강좌에서 머리 깨지고(너무 어려워서 꼭 다렉을 배워야 하나 싶은 고민을 좀 했습니다. 게다가 겨우 돈 모아서 산 강좌인데 제대로 이해도 못해서..), 게임 틀 만드는법부터 배우자는 느낌으로 유니티 강좌 달리고 있는데 너무 재밌네요... 개인적으로 4학년 올라가기 전까지 언리얼 강좌도 듣고 싶은데 가능할까요? 졸업작품으로 언리얼 강좌 보면서 그럴듯한 게임을 만들어보고 싶습니다...
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
12분 40초 질문
1. A라는 쓰레드가 Push에서 락을 잡는다.(다른애가 Push를 못하는 상황) 그리고 _jobQueue에다가 일감을 밀어 넣는다. 2. lock 안에서 flush가 true로 바뀌어서 Flush함수로 간다. 3. A쓰레드는 Flush함수에 들어와서 while문안에서 Pop을 한다. 4. Flush에서 Pop을 하는 순간 A는 락을 잡고 "_jobQueue.Count == 0" 이 될때까지 retrun _jobQueue.Dequeue();를 하면서 Flush의 while문을 돌게된다. ********* <질문> A라는 쓰레드가 Push에 와서 최초의 _flush를 true로 바꾸어 주어서 모든 쓰레드들이 접근이 가능한 _flush는 true인 상태여서 A가 Flush함수를 실행하러 계속 안에 있고 다른 B라는 쓰레드가 Push에와서 락을 잡고 일감을 밀어 넣는다고 해도 _flush는 true라서 Push안의 flush를 true로 바꿀 수 없어서 if (flush)에 조건이 안맞아 락만 걸고 일감을 밀어넣고 나오고 A만 Flush를 실행할 수 있고 A만 Flush함수에 계속 상주해 있고 다른애들이 계속 일감만 밀어 넣어주는 방식인가요?? Pop에서 락을 건 이유는 그냥 데이터를 안전하게 꺼내기 위함이고... 이렇게 이해했는데 맞을까요??
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Handler 질문 + 11분 질문
강사님이 13분 쯤에 실행 하는 부분에서 똑같이 cmd창에 10명이 입장은되는데 클라에서 보낸 메세지를 서버가 받아서 BroadCast하는 부분이 계속 호출이 안되었었습니다. 거의 3시간동안 뭐가 문제지?? 하다가 찾은 부분이 Server > PacketHandler부분에서 C_chatHandler부분이 이렇게 ClientSession clientSession = new ClientSession(); 되어 있어서 if문에 걸려서 그냥 return 을 해버린거 같은데 인자에 받은 session을 new ClientSession()으로 하게되면 새로 "빈" 갓난아기의?? ClientSession을 다시 만들어 버리기때문에 ClientSession의 Room이 항상 비어있는 상태라 retrun 으로 끝내버리게 되어서 ServerSessionManager의 Register하는 부분에서 _onRecv를 한다음 어떤 행동을 할것인가 == _handler 부분에서 매핑해놓은 C_chatHandler가 호출 되기는 하지만 new ClientSession 때문에 if에 걸려서 바로 return 을 하게 되어서 클라에 뿌려줄 수가 없었다.... 그래서 new ClientSession을 하면 안되고 여기서 이어서 받이온 session을 ClientSession으로 캐스팅을 하고 (안에 정보가 있으니까) 이어서 사용을 해야한다. 라고 이해를 했는데 어느정도 맞는 흐름일까요..??
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
코드오류 2
영상 17:38에 똑같이 작성했으나 오류가 발생해 왜 오류가 발생했는지 모르겠습니다.. 해결방법좀 알 수 있을까요
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
코드 오류
session #4 강좌의 15:45초 부분을 같이 따라했더니, 다음과 같은 오류가 발생했습니다.. 해결방법을 알려주실 수 있을까요? 의는 1:1 문의하기를 이용해주세요.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
7분 질문
현재 2022 버젼인데 프로젝트 파일은 이경로 있구요 PacketGenerator를 들어가보면 현재 이런 상태입니다 그런데 속성에 들어가서 이런식으로 출력 경로를 바꾸어 주어도 강사님이 하신것처럼 bin 산하에 생성이 안됩니다 .. 메모장으로 Append이거도 똑같이 했는데두요 오히려 이런 이상한 파일이 더 생겨 버렸습니다 ㅠ
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
AcceptAsync 이후 pending 관련
void RegisterAccept(SocketAsyncEventArgs args) { args.AcceptSocket = null; bool pending = _listenSocket.AcceptAsync(args); if (!pending) { OnACceptCompleted(null, args); } } 위 Function에서 보면 pending == false 인경우 OnACceptCompleted 함수를 바로 실행시키는데요 init 함수에서 SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.Completed += new EventHandler<SocketAsyncEventArgs>(OnACceptCompleted); RegisterAccept(args); 위와같이 args.Completed에 OnACceptCompleted를 등록해 주었기 때문에 펜딩이 안되어 바로 Accept가 된 상황에서도 등록한 이벤트로 인해 OnACceptCompleted 가 실행되는것 아닌가요? if (pending == false) { OnACceptCompleted(null, args); } 이 코드는 불필요 한게 아닌가 궁금합니다. 실제로 로그를 찍어보면 서버가 AcceptAsync를 하는 시점과 클라이언트가 접속하는 시간 차이가 있어서 pending이 항상 true로찍혔고 그래서 pending이 false일때에 대한 상황은 재현하지 못했습니다.
- 미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
jobQueue 질문 드립니다.
jobQueue 를 두는 이유가 기존에 thread 가 많아서 context-switching 비용이 더 비싸기 때문인가요? thread 숫자가 줄어서 결국 context-switching 비용을 아끼고 그만큼 성능이 빨라지게 되는 건지요?