VisualStudio/C#서버

[C#서버][방법] BitConverter 사용법 - ArraySegment<byte>, Span, Slice

usingsystem 2022. 10. 31. 10:36
728x90

BitConverter

BitConverter란 기본 데이터 형식을 바이트의 배열로, 바이트의 배열을 기본 데이터 형식으로 변환해주는 클래스이다.

배열에 데이터를 읽어온 후 배열에 담긴 데이터를 어떻게 기본 자료형으로 변환하는데 유용하다.


Bitconverter.GetBytes(문자열)

- 문자열 -> 배열 

Bitconverter.ToUInt16(읽을배열, 읽을위치)

- 배열특정위치 -> 문자열 (ushort일때 2바이트 추출)

 BitConverter.ToUInt16( new ReadOnlySpan<byte>())

- new ReadOnlySpan사용 하기 읽기전용, 안전성확보 excption

 public class Packet
    {
        public ushort size;
        public ushort packetId;
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            Packet packet = new Packet() { size = 10, packetId = 5 };

            ArraySegment<byte> openSegment = new ArraySegment<byte>(new byte[1024]);

            byte[] sizeByte = BitConverter.GetBytes(packet.size);
            byte[] packetIdByte = BitConverter.GetBytes(packet.packetId);
            Array.Copy(sizeByte, 0, openSegment.Array, openSegment.Offset, sizeByte.Length);
            Array.Copy(packetIdByte, 0, openSegment.Array, openSegment.Offset + sizeByte.Length, packetIdByte.Length);

            //ushort는 2바이트이기 때문에 두번째 버퍼에서 packetId를 추출하기 위해서 시작위치를 2로 써준다.
            ushort usize = BitConverter.ToUInt16(openSegment.Array, 0);
            ushort upacketId = BitConverter.ToUInt16(openSegment.Array, 2);

            //new ReadOnlySpan사용해서 추출, 직접 2를 넣는 대신 sizeof(ushort)를 넣어도됨
            //ushort usize = BitConverter.ToUInt16( new ReadOnlySpan<byte>(openSegment.Array, openSegment.Offset, openSegment.Count));
            //ushort upacketId = BitConverter.ToUInt16(new ReadOnlySpan<byte>(openSegment.Array, openSegment.Offset+2, openSegment.Count-sizeof(ushort)));

            Console.WriteLine($"size : {usize}, packetId : {upacketId}");
        }
    }

 

Bitconverter.TryWriteBytes(new Span(), 읽을 대상)

- 배열을 따로 생성하지 않고, 직렬화된 결과를 대상 byte[] 배열의 특정 위치에 바로 복사한다.

- array.copy를 사용하지 않고 바로 사용가능

※.Net Framework에서는 사용 못함. netCore에서 사용가능

public class Packet
    {
        public ushort size;
        public ushort packetId;
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            Packet packet = new Packet() { size = 10, packetId = 5 };
            ArraySegment<byte> openSegment = new ArraySegment<byte>(new byte[1024]);

            bool success = true;
            success &= BitConverter.TryWriteBytes(new Span<byte>(openSegment.Array, openSegment.Offset, openSegment.Count ), packet.size);    
            success &= BitConverter.TryWriteBytes(new Span<byte>(openSegment.Array, openSegment.Offset+2, openSegment.Count-2 ), packet.packetId);

            if (success == false)
                return;

            ushort usize = BitConverter.ToUInt16(openSegment.Array, 0);
            ushort upacketId = BitConverter.ToUInt16(openSegment.Array, 2);//ushort는 2바이트이기 때문에 두번째 버퍼에서 packetId를 추출하기 위해서 시작위치를 2로 써준다.

            Console.WriteLine($"size : {usize}, packetId : {upacketId}");
        }
    }

 

Bitconverter.TryWriteBytes(Slice , 읽을 대상)

slice(시작위치, 읽을범위)

  public class Packet
    {
        public ushort size;
        public ushort packetId;
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            Packet packet = new Packet() { size = 10, packetId = 5 };
            ArraySegment<byte> openSegment = new ArraySegment<byte>(new byte[1024]);

            Span<byte> s = new Span<byte>(openSegment.Array, openSegment.Offset, openSegment.Count);    

            bool success = true;
            success &= BitConverter.TryWriteBytes(s.Slice(0, s.Length), packet.size);
            success &= BitConverter.TryWriteBytes(s.Slice(sizeof(ushort), s.Length-sizeof(ushort)), packet.packetId);

            if (success == false)
                return;

            ushort usize = BitConverter.ToUInt16(openSegment.Array, 0);
            ushort upacketId = BitConverter.ToUInt16(openSegment.Array, 2);//ushort는 2바이트이기 때문에 두번째 버퍼에서 packetId를 추출하기 위해서 시작위치를 2로 써준다.

            Console.WriteLine($"size : {usize}, packetId : {upacketId}");
        }
    }
728x90