public bool TryParse(byte[] bytes)
        {
            if (bytes.Length < 20)
            {
                return(false);                // Check length
            }

            StunMessageType = (StunMessageType)BitUtils.FromBe((byte)(bytes[0] & 0b0011_1111), bytes[1]);

            if (!Enum.IsDefined(typeof(StunMessageType), StunMessageType))
            {
                return(false);
            }

            var length = BitUtils.FromBe(bytes[2], bytes[3]);

            MagicCookie = BitUtils.FromBeToInt(bytes.Skip(4).Take(4));

            TransactionId = bytes.Skip(8).Take(12).ToArray();

            if (bytes.Length != length + 20)
            {
                return(false);                // Check length
            }

            var list = new List <Attribute>();

            var b = bytes.Skip(20).ToArray();

            while (b.Length > 0)
            {
                var attribute = new Attribute(MagicCookieBytes.ToArray(), TransactionId);
                var offset    = attribute.TryParse(b);
                if (offset > 0)
                {
                    list.Add(attribute);
                    b = b.Skip(offset).ToArray();
                }
                else
                {
                    Debug.WriteLine($@"[Warning] Ignore wrong attribute: {BitConverter.ToString(b)}");
                    break;
                }
            }

            Attributes = list;

            return(true);
        }