안녕하세요. 강사님. 현재 사용할 수 있는 컴퓨터가 여러대인 학원 자습실에서 학습을 하고 있습니다. 현재 강의 내용이 새롭다보니 강의를 한 번 쭉 훓어보고 본격적으로 학습에 들어가려고 합니다. 질문을 하게 된 계기는 전에 소켓프로그래밍 채팅 예제를 할 때, 다른 컴퓨터에서 통신을 알려면 '공유기의 글로벌 IP주소'를 알아야한다고 해서 질문드리게 되었습니다. 여기서 질문 입니다. 노트북은 현재 없으며 컴퓨터가 여러 대 있는 환경 / 학원인지라 공유기 정보 및 글로벌 IP 주소를 알 수 없는 상황의 경우에는 이번 강의에서 학습할 예제를 하기 어려운지 미리 알고 싶습니다. (컴퓨터는 다 LAN선으로 꽂혀있고 LAN선의 최종 연결 위치는 보이지 않습니다.) 만약 어렵다면, 대처방안을 어떻게 해야할지도 알고 싶습니다.
안녕하세요! 강의 내용은 name을 받는 과정에서 byte[] 직렬화 및 역직렬화 하기 위해 nameLen을 count하고, 이를 ArraySegment에 넣는 과정인데요. 그 과정에서 다음과 같은 코드를 사용합니다. ServerSession.cs 이고, public override ArraySegment<byte> Write() 함수 내부입니다. // string ushort nameLen = (ushort)Encoding.Unicode.GetByteCount(name); success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), nameLen); count += sizeof(ushort); // nameLen(2) Array.Copy(Encoding.Unicode.GetBytes(name), 0, segment.Array, count, nameLen); count += nameLen; // name(n) 여기서 Array.Copy(Encoding.Unicode.GetBytes(name), 0, segment.Array, count, nameLen); 이 부분에서 count 대신 count + segment.Offset 를 사용하는 것이 올바르지 않을까 하여 질문드립니다. 이는 for문을 포함하여 코드 실행시 서버 측에서 다음과 같이 나타나기 때문입니다. Listening... PlayerInfoReq: playerId=1001, Name=NPC Received packet: size=20, packetId=1 PlayerInfoReq: playerId=1001, Name= Received packet: size=20, packetId=1 PlayerInfoReq: playerId=1001, Name= Received packet: size=20, packetId=1 PlayerInfoReq: playerId=1001, Name= Received packet: size=20, packetId=1 PlayerInfoReq: playerId=1001, Name= Received packet: size=20, packetId=1 Client connected: [fe80::9e56:3a99:3a3a:58be%18]:55626 OnDisconnected: [fe80::9e56:3a99:3a3a:58be%18]:55626 이처럼, 첫 1회만 NPC라는 네임이 제대로 나타나는 것을 볼 수 있습니다. 그러나 count + segment.Offset 를 사용했을 경우는, 다음과 같이 제대로 나타납니다. Listening... Client connected: [fe80::9e56:3a99:3a3a:58be%18]:55458 PlayerInfoReq: playerId=1001, Name=NPC Received packet: size=20, packetId=1 PlayerInfoReq: playerId=1001, Name=NPC Received packet: size=20, packetId=1 PlayerInfoReq: playerId=1001, Name=NPC Received packet: size=20, packetId=1 PlayerInfoReq: playerId=1001, Name=NPC Received packet: size=20, packetId=1 PlayerInfoReq: playerId=1001, Name=NPC Received packet: size=20, packetId=1 OnDisconnected: [fe80::9e56:3a99:3a3a:58be%18]:55458 물론 이후 리팩토링을 통해 작성한 코드에서는 전부 제대로 나타납니다. ushort nameLen = (ushort)Encoding.Unicode.GetBytes(this.name, 0, this.name.Length, segment.Array, segment.Offset + count + sizeof(ushort)); (리팩토링 코드) Offset을 사용하지 않을 경우 아마도 패킷을 덮어써서 이런 결과가 나타나는 것 같습니다.
ack number 설정에서 data 크기 + seq + 1 이라고 설명해주셨는데 seq가 1000부터 시작하고 데이터 크기가 500이라면 1000부터 1449까지의 데이터를 받은 것 아닌가요? 그러면 ack number가 1500으로 설정 되어야 하는 것 아닌가요??! 왜 +1이 더 생기는 지 궁금합니다 !
52강 ServerService 수강 중 13:54 때에 MakeShared함수를 이용해서 shared_ptr을 생성해주는 부분이 있는데, 똑같이 따라하던 중 제 프로젝트에서 컴파일 에러가 발생했습니다. 첨부해주신 프로젝트와 비교해보니 MakeShared함수가 변경되어 있더라구요 기존에 Memory 관련 강의 이후에는 변경된점이 없어서 어느 시점에 변경된건지 궁금합니다.
[게임 프로그래머 입문 올인원] C++ & 자료구조/알고리즘 & STL & 게임 수학 & Windows API & 게임 서버
ResourceManager::Clear() 에 해당하는 부분에 대해 질문이 있습니다. ResourceManager이 싱글톤으로 만들어지고, Game의 소멸자에서 또 ResourceManager의 Clear을 호출함으로써, Clear을 총 두번 호출하게 됩니다. 이 때, ResourceManager::Clear 내부에 unordered_map에서 메모리 해제를 하기 위해 SAFE_DELETE을 사용하고 있는데, for문이 auto mesh로 값복사를 하여 호출하는데, 이러면 힙 메모리는 delete시켰지만, map에서 관리되고 있는 포인터는 아직 해당 주소를 가리키고있어 두번째 Clear에서 또 값을 복사해오고 주소값자체는 복사해오므로 if(ptr)도 통과한 상태로 delete을 다시한번 시도하여 오류를 내는것으로 보입니다. 근데 궁금한건, 왜 Game의 소멸자로 싱글톤의 Clear을 호출하는 것인지, 각 매니저의 생명주기를 RAII로 관리하게 하면 이런 이중 삭제를 고려안해도 되지 않나요? 또한, for문으로 참조로 SAFE_DELETE를 한다면, Clear두번 호출되어도 이중 삭제 방지되지만, 왜 map의 clear로 해당 상황을 방지하는 선택을 하셨는지 궁금합니다.
클라이언트에서는 모든 체력바가 보이고 서버에서는 클라이언트 머리 위에 체력바가 보이질 않습니다/ 실제로, 9강에서 했던 체력 동기화까지 잘됩니다. 9강 끝났을 때도 같은 현상이 있긴했는데 일단 진행했는데 제가 어느 부분을 체크해야 고칠 수 있을까요 ? 언리얼 버전 5.5 사용중입니다.
클라이언트에서는 모든 체력바가 보이고 서버에서는 클라이언트 머리 위에 체력바가 보이질 않습니다/ 실제로, 9강에서 했던 체력 동기화까지 잘됩니다. 9강 끝났을 때도 같은 현상이 있긴했는데 일단 진행했는데 제가 어느 부분을 체크해야 고칠 수 있을까요 ? 언리얼 버전 5.5 사용중입니다.
안녕하세요, 널널한개발자님 ^^ 정말 좋은 강의를 통해 네트워크 학습중이라 정말 재밌습니다. 'TTL과 단편화' 강의를 시청중에 한가지 의문점이 생겨 질문드립니다. 만약 영상에서 언급하신 것 처럼 거치는 라우터 중에 MTU가 송신측보다 낮은 크기를 사용하는 것이 있으면, 이는 하향평준화를 통해 단편화를 최소화 하거나, 단편화가 발생하면 서버(수신)측에서는 다시 패킷을 조립한다고 하셨습니다. 하지만 한가지 궁금점이, 만약 송신측에서 MTU를 1.5KB로 보내고, 모든 라우터의 MTU 또한 1.5KB이기에 잘 전달되던중, 서버측에 도달하기 직전 서버의 MTU가 1.4KB라서 단편화가 발생하게 된다면, 서버측에서 프래그먼트를 추출하는 방식이 달라지거나(다시 패킷을 조립할 수 없기때문, MTU가 다르기에) 성능 이슈? 같은 것도 생길 수 있을것 같은데(다시 데이터 스트림으로 변경해야하기 때문에) 이러한 상황에서 어떻게 되는지가 궁금합니다. 답변 해주시면 감사하겠습니다 :)
안녕하세요. 이제 sprint1 을 통해 기본적인 개념정도만 습득한 상태입니다. spring boot 애플리케이션 -> K8s 배포를 기준으로 실제 앱 내에서 사용되는 환경변수 설정과 K8s내의 컨피그맵, 시크릿 등에 대한 설정 매칭 등을 보고 싶은데 sprint 1 -> 지금 강의를 먼저 수강 해도 이해가 괜찮을까요? [ 👍 좋은 질문을 했을 때 좋은 답변이 돌아 옵니다] 1. 실습 중 본인의 환경이 가이드와 다른 부분이 있었다면 말씀해주세요. 2. 해당 문제의 발생 빈도(재설치 여부)와 문제 해결을 위해 시도해본 케이스를 말씀해 주시면 원인 파악에 큰 도움이 됩니다. 3. 에러 메시지만 봐서는 저도 모르는 경우가 많아요. 그전에 했던 작업이 포함된 캡쳐 화면도 부탁 드려요. 4. 영상 내용에 대한 질문 시 해당 시간을 같이 올려 주시면 답변을 드리는 시간이 더 빨라집니다. 5. 긴 로그는 제 메일로 보내주세요. ( k8s.1pro@gmail.com ) 6. 카페 [ 강의 자료실 ]에도 많은 질문과 답변들이 있어요!
[게임 프로그래머 입문 올인원] C++ & 자료구조/알고리즘 & STL & 게임 수학 & Windows API & 게임 서버
아직 다음 강의를 안들어서 잘 예측이 안되지만, owner에 보통 이벤트를 발생시킨 Session의 shared_from_this()를 넣어줄 것으로 예상을 해봅니다. 만약 이 상황에서 io작업이 밀려 오래 걸리거나 누락되어 shared_ptr로 물고 있던 session들이 해제 안되는 문제가 생길 수 있지 않나요? 그렇기 때문에 weak_ptr로 owner을 관리하고, 다만 session이 만료되어 없어지면 유효하지 않은 이벤트이므로 .lock()을 통해 nullptr로 반환 시 예외 처리해주는게 더 안전하지 않나요? 공부를 더 해야겠지만, 사실 아직 잘 이해가 안갑니다. owner와 event등의 수명 주기가 어떤 관계가 있는지 정확히 모르겠지만 방향성을 알려주시면 감사하겠습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문 전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. 섹션9 : 네트워크 - 프로그램2 55. 네트워크 프로그램5 - 자원 정리2 여기 SessionV5에서 try-with-resources를 적용하기 위해 try에 소캣 input, output 다 넣는데 제가 실수로 socket을 넣지 않고 다른 코드 다 작성후 코드를 실행했는데 마지막에 잘 정리된건지 확인하는 로그 log("연결 종료 : " + socket + "isClosed : " + socket.isClosed()); 여기서 true로 나오는데 이건 윈도우라서 그런건가요? 부가 설명부분에 윈도우 os는 tcp연결 강제 종료하기때문에 EOFExcepoin이 아니라 SocketException : Connection reset 이런 예외가 발생한다고 설명이 되어있어서 소캣을 빼먹고 자원정리해도 그냥 정리된 상태로 표시되는건지 궁금합니다.
지금까지 개발한 서버코어는 IOCP기반의 비동기 논블로킹 방식이라 생각됨니다.Send에서는 SendBuffer를 sendEvent에 등록한 다음 Scatter-Gather로 모아서 ::WSASend로 송신을 수행하는 것으로 이해했습니다.Recv에서는 ::WSARecv에서 수신을 받기 전에 버퍼에 패킷 데이터를 조립한 다음에 바로 함수를 실행하고 있습니다.이벤트 데이터는 사실상 비어있고 callback함수도 없으니 ::WSARecv는 수신완료를 CP에 보내는 것 밖에 없다고 봅니다.제가 볼때 수신부는 제가 이해한 비동기 방식과는 다르게 돌아가는 것 같습니다.어떻게 이해해야 할까요?
강의 2분정도부터 나오는 설명에 대해서 서버에서 close()하여 보내는 1.FIN 을보내고 이에 대한 응답으로 OS에서는 2. ACK를 전달합니다. 이제 클라이언트에서도 close() 하여 FIN을 보내는데 이때 ACK도 같이 보내어 3. FIN + ACK 함께보내는데요, 이때 ACK는 무엇에 대한 응답인건가요? 2. ACK 에 대한 응답인건가요? 응답을 잘받았다고 응답하는건지..