반응형

session 30

Part 4-4-1. 패킷 직렬화 : Serialization #1

패킷 직렬화 지난 시간까지 Session, Connector, RecvBuffer, SendBuffer, PacketSession 등 다양한 클래스를 만들어 패킷 통신에 대해서 진행해보았다. 또한 통신하는 과정에서의 개선, 최적화 등 다양한 방식의 작업 또한 추가적으로 진행해보았다. 이번 세션에서는 패킷 직렬화를 통해 String, List 등 다양한 타입을 가지는 자료형들에 대해서 어떻게 전송이 필요하고, 어떤 방식으로 압축해야 하는지 등 보다 자세하게 알아보자. 📌 직렬화 마이크로소프트 공식 홈페이지에 따르면 C#(.NET)에서의 직렬화란 '지속시키거나 전송할 수 있는 형태로 개체 상태를 변환하는 프로세스'를 뜻한다. 그렇다면 왜? 직렬화를 사용해야 하고 이용해야할까? 이는 간단하다. String, ..

Part 4-3-13. 네트워크 프로그래밍 : PacketSession

네트워크 프로그래밍 지난 시간에는 SendBuff 클래스를 만들었다. 클래스 내부에는 버퍼로 활용해 줄 recvBuffer, 사용한 영역을 표기하는 usedSize, 남은 공간의 크기를 나타내는 FreeSize를 선언해준다. 또한 메서드로는 Receive와 같이 Open, Close 함수를 만들어었지만, Receive와는 다르게 Clean 함수는 만들어주지 않았다. 🤔 이 후, TreadLocal을 이용한 SendBufferHelper를 만들어 SendBuff 클래스 내부를 건드리지 않고 사용하였다. 패킷 전송하기 📤 패킷을 전송하는 방법까지 알아보았지만, 정작 패킷만 보았을 때 패킷의 사이즈가 어느정도인지 아직은 알 수 없다. 따라서 보통 패킷의 첫 번째 인자로는 사이즈를 넣어주고, 두 번째 인자로는 ..

Part 4-3-12. 네트워크 프로그래밍 : SendBuffer

네트워크 프로그래밍 지난 시간에는 ReceiveBuff를 만들어서 Read, Write Pos(=Segment)를 생성하였다. 이러한 과정에서 byte를 받아오고, 또 받아온 byte를 처리하는 로직을 작성하였다. 또한 중간중간 R/W Pos를 초기화해주는 Clear 함수, 작업이 완료 된 이후 OnRead, OnWrite 처리를 하는 메서드 또한 만들었다. 기존 Send의 문제점 기존 Send는 Encoding을 진행한 후, byte 타입으로 전환하여 이를 넘겨주고, 넘겨준 Send Queue에 저장하여 처리하는 방식으로 진행하였다. 이번 시간에는 기존에 Encoding으로 처리하던 방법을 이번에는 실질적인 패킷 데이터로 가정하고 넘겨 받기 위해 Send Buffer를 만들어 줄 것이다. 😎 Recei..

Part 4-3-11. 네트워크 프로그래밍 : RecvBuffer

네트워크 프로그래밍 지난 시간에는 TCP와 UDP 각각의 개념들에 대해서 알아보고, 또 '차이점은 무엇이 있는가?'에 대해서 학습하였다. 오늘은 이전 시간에 학습한 것과 마찬가지로 TCP 특성 중 현재 처리 가능한 패킷만 받고, 나머지는 나중에 처리하는 흐름제어 및 혼잡제어 기능을 구현하여 어떻게 처리하는지 알아보며 구현한다. 기존 코드의 문제점 기존 코드는 시작 시 SetBuffer의 위치를 0으로 설정해놓았기 때문에 TCP 특성상 100byte를 보내어도, 80byte만 받았을 경우 문제가 발생한다. 왜냐하면 80byte의 위치부터 나머지 20byte을 다 받은 후에 처리를 해야하기 때문이다. 따라서 현재 얼마나 받았고, 받아왔는지를 처리하며 표시할 방법이 필요하다. RecvBuffer 클래스 제작 ..

Part 4-3-10. 네트워크 프로그래밍 : TCP/UDP

네트워크 프로그래밍 지난 시간에는 Connector를 이용하여 ServerCore 프로젝트를 라이브러리화 하는 작업을 진행했다. 이번 시간에는 실질 적으로 패킷을 전송하고, 수신하는 부분을 만들 것이다. 그렇지만 우리 프로젝트는 현재 string으로만 데이터를 전송하고 있는데, 현업에서는 string 형태로 패킷을 전송하지 않기 때문에 이를 수정해야한다. 하지만 어떻게? 무슨 방법으로? 등 패킷 통신처리에 대한 다양한 대한 궁금증이 생기게 되는데 이 때 사용할 수 있는 방법이 TCP/UDP가 있다. 따라서 오늘은 TCP와 UDP에 대해서 다시금 알아보는 시간을 가진다. 예제 😎 간단하게 예를 들어보자. 우리가 아무것도 모르지만 TCP를 이용해 서버를 구성한다고 하면, TCP의 특징 떄문에 우리가 클라이언..

Part 4-3-9. 네트워크 프로그래밍 : Connector

네트워크 프로그래밍 지난 시간에는 Session을 상속하는 과정과 총 4가지의 Event Handler(OnConnected, OnRecv, OnSend, OnDisconnected )를 이용하여 구현하는 시간을 가졌다. 이번 시간에는 Connector를 만드는 시간을 가진다. 👍 Connector를 만들기 전에, 왜 만들어야 할까? 클라이언트와 서버간의 통신은 당연히 필요하기 때문에 구현하는 것이 맞지만, 서버만 이용하고 있는 곳에 왜 Connecotr가 필요할까? 그 이유는 다음과 같다. 1. 현재 서버 코어 같은 경우에는 서버를 메인 용도로 만들고 있지만 커넥트, 샌드, 리시브 하는 부분은 사실 공용으로 사용하면 좋다. 2. 서버 또한 분산처리를 할 수 있기 때문에 서버끼리의 연결과 통신이 필요하다..

Part 4-3-8. 네트워크 프로그래밍 : Session #4 (Event Handler)

네트워크 프로그래밍 지난 시간에서 우리는 Session을 만들어 소켓 프로그래밍의 Receive 부분과 Send 부분을 분리하여 작업이 진행되도록 처리 했다. 오늘은 Recv 부분의 코드 로직을 서버 단과 컨텐츠 단을 나누어서 작업이 진행될 수 있도록 개선할 것이다. 이 작업은 이벤트 핸들러를 이용하는 방법과, 상속을 이용하는 방법이 있지만 루키스님은 상속이 보다 구현하기 쉽기 때문에 상속 방법을 통해 이를 구현한다. 😎 Session 클래스 내 상속 메서드 추가 먼저 우리가 무엇을 사용해야 되는지 다시 한번 생각해보아야 한다. 이를 곰곰이 생각해 나누어 보면 크게 4가지로 나뉘어 질 수 있는 것을 알 수 있다. 1. 어떤 클라이언트에서 접속을 했는지 알 수 있는 OnConnected 2. 클라이언트가 ..

Part 4-3-7. 네트워크 프로그래밍 : Session #3 (Send 개선)

네트워크 프로그래밍 지난 시간에서 우리는 새로운 클래스인 Session을 만들어 소켓 프로그래밍의 Receive 부분과 Send 부분을 분리하여 작업을 진행했다. 오늘은 이어서 Send 부분의 코드 로직을 조금 더 우아하게 사용하기 위해 개선할 것이다. Send 개선 class Session { Socket _socket; int _disconnected = 0; object _lock = new object(); Queue _sendQueue = new Queue(); List _pendinglist = new List(); SocketAsyncEventArgs _recvArgs = new SocketAsyncEventArgs(); SocketAsyncEventArgs _sendArgs = new So..

Part 4-3-6. 네트워크 프로그래밍 : Session #2 (Send 분리)

네트워크 프로그래밍 지난 시간에서 우리는 새로운 클래스인 Session을 만들어 소켓 프로그래밍의 Receive 부분을 분리하여 작업을 진행했다. 오늘은 이어서 Send 부분을 분리하여 비동기로 처리할 것이다. Send 비동기 처리 구현 Send는 Receive 와는 다르게 언제, 어디서, 얼마의 버퍼(Buffer)의 크기를 사용하여 보낼지 모르기 때문에 기존 구조와는 다르게 비동기 처리 구현이 필요하다. Send의 동작 구조는 기존의 Receive의 동작 구조와 유사하다. 하지만 Start 메서드에서 SocketAsyncEventArgs 클래스를 이용해 소켓을 생성했던 기존의 Receive와는 달리 Send에서는 이벤트만을 연결해 줄 것이다. 왜 이렇게 처리해야 할까? 기존의 Receive 동작 구조는..

Part 4-3-5. 네트워크 프로그래밍 : Session #1 (Receive 분리)

네트워크 프로그래밍 우리는 이전 시간에 Accept를 비동기 함수로 변경했다. 그래서 해당 로직이 AcceptAsync 👉 RegisterAccept 👉 OnAcceptCompleted를 왔다갔다 하면서 호출이 되게끔 했다. 그러나 이 함수를 자세히 보면 '혹시 RegisterAccept 메서드 내 pending의 값이 false 처리가 되어 재귀적으로 뺑뺑이를 돌다 스택 오버플로우가 일어나지 않을까?'라는 의문이 들 수 있다. 그리고 이는 이론상으로는 가능하다. 하지만 이는 현실적으로는 일어날 수 없다. 왜냐하면 우리는 Init() 메서드 내부에서 Listen의 값을 10으로 설정해주었기 때문이다. 따라서 동시 다발적으로 pending의 값이 false로 뜨는 것은 현실적으로 일어날 수 없다. 또 현재..

반응형