본문 바로가기
cs공부/네트워크프로그래밍

네트워크프로그래밍 - 패킷 자동화 처리 객체지향 방법으로 수행하도록 하기

by 코딩하는 돼징 2023. 8. 7.
반응형

패킷 자동화 처리 알아보러 가기

 

네트워크프로그래밍 - 패킷 자동화 처리(TryWriteBytes,c#에서 포인터 사용하는 법)

패킷작업하기 서버, 클라이언트에 이 정보가 다 있어야 한다. class Packet { public short size; public short packetId; } class PlayerInfoReq : Packet { public long playerId; } class PlayerInfoOk : Packet { public int hp; public int atta

code-piggy.tistory.com


객체지향 방법 사용하기

패킷을 만든 다음에 해야되는 부분이 너무 많다. 그러므로 밀어 넣어주는 부분을 따로 빼서 객체지향 방법을 사용하는 것이 좋다. 


1. Write

01 기존 코드

ArraySegment<byte> openSegment = SendBufferHandler.Open(4096);
bool success = true;
ushort count = 0;

count += 2;
success &= BitConverter.TryWriteBytes(new Span<byte>(openSegment.Array, openSegment.Offset + count, openSegment.Count - count), packet.packetId);
ㅌcount += 2;
success &= BitConverter.TryWriteBytes(new Span<byte>(openSegment.Array, openSegment.Offset + count, openSegment.Count-count), packet.playerId);
count += 8;

success &= BitConverter.TryWriteBytes(new Span<byte>(openSegment.Array, openSegment.Offset, openSegment.Count),count);
ArraySegment<byte> sendBuff = SendBufferHandler.Close(count);

02 인터페이스 설정

Write : 직렬화 작업을 수행

Read : 역직렬화 작업을 수행

public abstract class Packet
{
    public ushort size;
    public ushort packetId;

    public abstract ArraySegment<byte> Write();
    public abstract void Read(ArraySegment<byte> s);
}

03 Write, Read메서드 구현 및 생성자 설정

packetId는  네트워크 통신에서 패킷의 종류를 식별하는데 사용된다. 이를 생성자가 호출될때마다 packetId를 설정되도록 한다.

class PlayerInfoReq : Packet
{
    public long playerId;
        
    public PlayerInfoReq()
    {
        this.packetId = (ushort)PacketID.PlayerInfoReq;
    }
        
    public override void Read(ArraySegment<byte> s)
    {
    }

    public override ArraySegment<byte> Write()
    {
    }
}

04 Write메서드

public override ArraySegment<byte> Write()
{
    ArraySegment<byte> openSegment = SendBufferHandler.Open(4096);
    bool success = true;
    ushort count = 0;

    count += 2;
    success &= BitConverter.TryWriteBytes(new Span<byte>(openSegment.Array, openSegment.Offset + count, openSegment.Count - count), this.packetId);
    count += 2;
    success &= BitConverter.TryWriteBytes(new Span<byte>(openSegment.Array, openSegment.Offset + count, openSegment.Count - count), this.playerId);
    count += 8;
    
    success &= BitConverter.TryWriteBytes(new Span<byte>(openSegment.Array, openSegment.Offset, openSegment.Count), count);
    return SendBufferHandler.Close(count);
}

기존 코드와의 차이

this.packet, this.playerId와 같이 현재 클래스 내의 변수를 사용하여 데이터에 접근한다.


ArraySegemt

public static bool operator ==(ArraySegment<T> a, ArraySegment<T> b);

ArraySegemt<T>의 두개의 구조체를 비교해서 동일한지 여부를 확인할 수 있는 메서드이다. 만약 내용과 길이가 같다면 true를 반환하고 아닐 경우 false를 반환한다.

이를 이용해서 데이터 변환작업의 성공여부에 대한 추가 처리할 수 있다.

if (success == false)
{
    return null;
}

05 최종 결과

packet객체의 Write메서드를 호출하고 데이터를 ArraySegement<byte>형식으로 받아온다.

ArraySegment<byte> s = packet.Write();

if (s != null)
    Send(s);

2. Read

01 기존 코드

switch((PacketID)id)
{
    case PacketID.PlayerInfoReq:
    {
        long playerid = BitConverter.ToUInt16(buffer.Array, buffer.Offset + count);
        count += 8;
        Console.WriteLine($"PlayerInfoReq: {playerid}");
    }
    break;
}

02 Read메서드

ArraySegment<byte>에서 데이터를 역직렬화 한 다음 playerId 필드에 할당하는 작업을 수행

public override void Read(ArraySegment<byte> openSegment)
{
    ushort count = 0;
    //ushort size = BitConverter.ToUInt16(openSegment.Array, openSegment.Offset);
    count += 2;
    //ushort id = BitConverter.ToUInt16(openSegment.Array, openSegment.Offset + count);
    count += 2;

    this.playerId = BitConverter.ToUInt16(openSegment.Array, openSegment.Offset + count);
    count += 8;
}

03 최종 결과

원래 직접 역직렬화하여 값을 얻어왔는데, 이제는 PlayerInfoReq클래스의 인스턴스를 생성화고 Read메서드를 호출하여 역직렬화 작업을 수행한다.

switch((PacketID)id)
{
    case PacketID.PlayerInfoReq:
    {
        PlayerInfoReq p = new PlayerInfoReq();
        p.Read(buffer);
        Console.WriteLine($"PlayerInfoReq: {p.playerId}");
    }
    break;
}

3. 결과

 

 

 

 

 

 

 

 

 

참고 :  본 내용은 MMORPG  PART4 강의를 수강하여 작성하였습니다.

https://www.inflearn.com/course/%EC%9C%A0%EB%8B%88%ED%8B%B0-mmorpg-%EA%B0%9C%EB%B0%9C-part4

 

 

 

 

 

 

 

 

반응형

댓글