Server programming61 03_10_패킷 직렬화_PacketGenerator #5_ switch문의 비효율성 개선, case 파싱 자동화 다룰 내용 및 요약 프로토콜이 많이 늘어날 경우 switch문의 비효율성을 개선하고 case문을 만들고 파싱하는 것을 자동화하고자 합니다. 다음과 같은 단계를 진행합니다. 프로토콜이 많이 늘어날 경우 switch문의 비효율성을 개선하고 case문을 만들고 파싱하는 것을 자동화하고자 합니다. 다음과 같은 단계를 진행합니다. IPacket 인터페이스를 정의하고 구현합니다. 자동화를 위해 PacketFormat을 수정하고, .bat 파일로 갱신합니다. ClientSession의 OnRecvPacket 코드를 자동화합니다. 3-1) 코드 이주 PacketHandler와 PacketManager 클래스를 생성하고 ClientSession의 OnRecvPacket에서 받은 데이터를 사용하는 코드를 옮겨줍니다. Pa.. Server programming 2023. 4. 20. 03_09_패킷 직렬화_PacketGenerator #4_패킷 파일 자동 생성 배치 지난 시간에 생성된 코드를 ServerSession, ClientSession에 각각 수동으로 붙여 넣는게 문제였습니다. 패킷은 컨텐츠 만들면서 계속 변화할텐데 만들 때 마다 수동으로 복사하는 건 힘드니까 오늘은 그 부분을 자동으로 처리하는 방법을 알아볼 것 입니다. 이를 위해 다음과 같은 과정을 거칩니다. GenPackets.cs이 생성될 장소 만들기 PDL의 경로를 받을 string 변수 선언 실행 파일 및 빌드된 파일이 생성되는 위치 변경 PDL의 기본 경로 설정 bat파일을 이용해 GenPacket.cs 생성 GenPacket.cs 생성되는 위치를 bat파일에서 설정 1. GenPackets.cs이 생성될 장소 만들기 DummyClient→추가→ 새항목 GenPackets라는 클래스를 만들어 준다.. Server programming 2023. 4. 19. 03_08_패킷 직렬화_PacketGenerator#3_전체 코드 생성 이번 시간에 한 내용 GetPacket.cs 파일 안의 전체 코드 생성을 위한 포멧을 정의 하고 그걸 이용해 코드를 생성한다. PDL에 패킷이 여러개로 정의 된 경우 테스트 한다. 생성된 코드가 정렬되게 수정한다. 타입이 byte인 경우 처리될 수 있게 코드 포멧을 추가하고 코드를 생성한다. 2중 List가 지원되는지 테스트 한다. 1. 파일 자체에 대한 포멧 정의 하기 지난 시간에 패킷 자동화에 대한 윤곽을 봤었는데 이제 앞으로는 GenPackets.cs에 있는 내용을 수동으로 복붙해서 붙여 넣는게 아니라, GenPackets라는 파일 자체든 클라든 서버든 필요한 쪽에서 참조를 해가지고, 사용하게끔 수정을 해야 한다. 이 파일이 완전체로 사용되기 위해서 뭐가 빠졌는지 생각을 해보면, ServerSess.. Server programming 2023. 4. 18. 03_07_패킷 직렬화_PacketGenerator #2_코드 자동 생성, List 추가 지난 시간에 작업한 코드를 이용해서 주어진 입력을 기반으로 패킷을 생성하고, 생성된 패킷을 GenPackets.cs 파일에 저장해 그 코드를 이용해 실제로 작동하는시 실험 해 봅니다. 지난 시간에 안해준 List의 코드를 만드는 부분도 작성해 봅니다. 지난 시간에 이걸 왜 했는지 아직 와닿지 않을 수 있는데 코드를 만들어 보면 쉽게 이해가 갈 것이다. 다시 프로그램으로 돌아와서 결국에는 우리가 하고 싶은 건 무엇이냐 namespace PacketGenerator { class Program { static void Main(string[] args) { XmlReaderSettings settings = new XmlReaderSettings() { IgnoreComments = true, IgnoreW.. Server programming 2023. 4. 18. 03_06_패킷 직렬화_PacketGenerator #1_XML파일 사용해 자동으로 패킷 생성하기 위한 첫 작업 이번 포스팅에서는 자동으로 패킷을 생성하는 방법에 대해 설명합니다. 먼저, XML 파일을 사용하여 패킷의 포맷을 정의하고, 이를 기반으로 자동으로 패킷을 생성하는 방법에 대해 다룹니다. 그 과정 중의 첫단계로 XML 파일을 만들어 보고, Main에서 XmlReader를 이용해 읽어들여 출력을 하고, 더 나아가 Xml 파일의 전부가 아닌 packet부분만 출력을 하기 위해 Parse하는 코드와 PacketFormat을 만드는 작업을 해 봅니다. 자동화 할 때 거치게 되는 단계 : 하드코딩으로 만들어 본 다음에 (이전 시간까지의 작업) 최대한 재사용할 수 있는 것들을 자동화 코드로 빼주면 된다. (이제 할 것) 지난 시간까지 작업한 코드에서 Packet을 사용하지 말지가 고민이야. size랑 packetId.. Server programming 2023. 4. 14. 03_05_패킷 직렬화_Serialization #4_List< > 확인 테스트 Q1. List를 직렬화 하기 위해 한 작업들을 나열해 보세요. → -> PlayerInfoReq 클래스에 SkillInfo구조체를 선언하고, 그 구조체를 들고 있는 List인 skills를 생성한다. public struct SkillInfo { public int id; public short level; public float duration; } public List skills = new List(); ->ServerSession의 Write에 List가 가지고 있는 갯수를 buffer에 밀어 넣고, foreach로 List를 순회한다. // skill list success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - coun.. Server programming 2023. 4. 13. 03_04_패킷 직렬화_Serialization #3_string 확인 Test Q1. string의 경우 long이나 ushort와 달리 파싱할 때 문제가 있는 이유가 무엇인가? ->길이를 알지 못하기 떄문에 ToInt64나 ToInt16같은 걸 써서 파싱할 수 없다. Q2. 코드를 깔끔하게 해주기 위해 어떤 개선을 해줬는가? -> 상수를 sizeof를 이용해 바꿨고, Span의 범위를 다시 집을 때 Slice를 사용했다. Q3. string을 buffer에 밀어 넣을 때 UTF-16을 선택하는게 나은 이유는? -> C#에서 string이 기본적으로 UTF-16으로 되어 있기 때문이다. Q4. string이 몇 바이트인지 모르기 때문에 몇 바이트 짜리가 와야 성공적으로 조립을 할 수 있는건지 알기 힘들다. 이 때 해결책은? -> string의 length를 먼저 2바.. Server programming 2023. 4. 12. 03_03_패킷 직렬화_UTF-8 vs UTF-16 Q1. Ascii, 유니코드, UTF-8, UTF-16의 특징을 설명해 보세요 → 유니코드와 인코딩 유니코드는 문자를 고유한 코드 포인트로 매핑하는 규격으로, 컴퓨터가 문자를 이해할 수 있도록 합니다. 인코딩은 유니코드 문자를 바이트로 변환하는 방법입니다. 주요 인코딩 방식에는 UTF-8과 UTF-16이 있습니다. ASCII 코드 ASCII 코드는 1바이트로 문자를 표현하는 방식입니다. 하지만 다양한 언어를 표현하기에는 한계가 있어, 유니코드가 등장했습니다. 유니코드 유니코드는 2바이트로 대부분의 문자를 표현할 수 있지만, 일부 문자는 3바이트가 필요합니다. 이를 효율적으로 표현하기 위해 가변 길이 인코딩 방식이 등장했습니다. UTF-8 UTF-8은 가변 길이 인코딩 방식으로, 영문은 1바이트, 한글은 .. Server programming 2023. 4. 11. 03_02_패킷 직렬화_Serialization #2_자동화 확인 테스트 Q1. 어떻게 자동화를 하면 좋을까요? -> 쓰는 부분과 읽는 부분을 함수로 빼서 Packet클래스를 상속받은 PlayerInfoReq클래스에 정의해 사용합니다. Q2. Write와 Read의 다른 점은 무엇인가요? -> 전부 다 Read에서 뽑는게 아니라 size와 id는 OnRecvPacket에서 뽑고 playerId만 Read에서 뽑는다. Q3. Read에서 size와 id를 추출할 필요가 없는 이유는 무엇인가요? -> size와 id는 OnRecvPacket에서 뽑고 Read를 호출하기 때문이다. Read가 같은 buffer를 넘겨 받고 같은 프로토콜을 사용하고 있기 때문이다. Q4. Read에서 무엇을 하는가? ->PlayerInfoReq의 멤버 변수 playerId의 값을 buff.. Server programming 2023. 4. 11. 03_01_패킷 직렬화_Serialization #1_기본 확인 테스트 Q1. 직렬화, 역직렬화란 무엇을 말하는 것인가? -> 어떤 인스턴스로 존재하는 애를 납작하게 만들어서 buffer안에 밀어 넣는 작업이 직렬화, byte로 되어 있는 애를 꺼내쓰는 작업을 역직렬화 Q2. DummyClient에 ServerSession, Server에는 ClientSession을 만든 이유가 무엇인가? 또 이렇게 이름을 나눈 이유는 무엇인가? -> Server에 Client의 대리인으로 있는게 ClientSession이고, Client에 Server의 대리인으로 있는게 ServerSession이기 때문이다. 이름을 나누는 이유는 나중에 분산서버를 만들게 되면 각 다른 부분을 관리하는 서버의 대리자 역할을 할 Session이 필요할 것이기 때문이다. Q3. 어떤 프로세스로 코.. Server programming 2023. 4. 11. 02_14_네트워크 프로그래밍_PacketSession 확인 테스트 Q1.Packet이 완전체로 왔는지 짤려서 왔는지 구분하려면 어떻게 해야 할까요? 유동적으로 커졌다 작아졌다 하는 패킷의 경우 어떻게 해야 할까요? -> 첫인자로 size를 넣어준다. (두번째 인자로 Id를 넣어준다.) Q2. Session의 Session을 상속받은 PacketSession클래스를 추가하고 OnRecv는 sealed 를 붙이고, OnRecvPacket 함수를 abostract를 붙여 새로 선언한 이유는 무엇인가요? -> PacketSession을 상속받는 애들은 이 OnRecv인터페이스가 아니라 별도로 건내주는 public abstract void OnRecvPacket();이라는 인터페이스로 받아 사용하라는 의도 Q3. PacketSession의 OnRecv에서 buffe.. Server programming 2023. 4. 8. 02_13_네트워크 프로그래밍_SendBuffer 확인 테스트 Q1. 작업한 것을 나열해 보세요. Q2. send와 recv의 다른 점은 무엇인가? Q3. 왜 sendBuffer는 sesseion안에 넣을 수 없는 걸까? Q4. sendBuffer는 clean 기능 없이 1회용으로 사용하는 이유는? Q5. SendBuffer를 보면 멀티 스레드 처리를 안해줘도 괜찮은 이유는? Q6. 왜 Server에 sendBuff가 있으면 공용이 되고, Session에 있으면 고유의 버퍼를 갖게 되는건가? 답안 1. -> Server에 Knight 클래스를 추가한다 -> Server의 OnConnected(EndPoint endPoint)의 코드를 수정한다. 메시지가 아닌 sendBuff를 생성하고, Knight를 byte[]로 전환해 Send에 전달하게 바꾼다. -.. Server programming 2023. 4. 7. 이전 1 2 3 4 5 6 다음