Exemple #1
0
 public SetChunkSizeMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader = new RTMPBinaryReader(new MemoryStream(x.Body))) {
         ChunkSize = (int)Math.Min(0x7FFFFFFL, reader.ReadUInt32());
     }
 }
Exemple #2
0
        public AggregateMessage(RTMPMessage x)
            : base(x)
        {
            var messages = new List <RTMPMessage>();

            using (var reader = new RTMPBinaryReader(new MemoryStream(x.Body))) {
                while (reader.BaseStream.Position < reader.BaseStream.Length)
                {
                    var message_type = (RTMPMessageType)reader.ReadByte();
                    var length       = reader.ReadUInt24();
                    var timestamp    = reader.ReadUInt32();
                    var stream_id    = reader.ReadUInt24();
                    var body         = reader.ReadBytes(length);
                    var msg          = new RTMPMessage(
                        message_type,
                        timestamp + x.Timestamp,
                        x.StreamId,
                        body);
                    var prevlen = reader.ReadUInt32();
                    if (prevlen == body.Length + 11)
                    {
                        messages.Add(msg);
                    }
                }
            }
        }
Exemple #3
0
 public SetWindowSizeMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader = new RTMPBinaryReader(new MemoryStream(x.Body))) {
         WindowSize = reader.ReadUInt32();
     }
 }
        private async Task HandshakeOld(RTMPBinaryReader c1reader, CancellationToken cancel_token)
        {
            var s1vec = new byte[1528];
            var rand  = new Random();

            rand.NextBytes(s1vec);
            await SendAsync(writer => {
                writer.Write(0);
                writer.Write(0);
                writer.Write(s1vec);
            }, cancel_token).ConfigureAwait(false);

            var c1time = c1reader.ReadInt32();
            var c1ver  = c1reader.ReadInt32();
            var c1vec  = c1reader.ReadBytes(1528);

            await SendAsync(writer => {
                writer.Write(c1time);
                writer.Write(c1ver);
                writer.Write(c1vec);
            }, cancel_token).ConfigureAwait(false);

            using (var reader = await RecvAsync(1536, cancel_token).ConfigureAwait(false)) {
                var c2time = reader.ReadInt32();
                var c2zero = reader.ReadInt32();
                var c2vec  = reader.ReadBytes(1528);
                if (!s1vec.SequenceEqual(c2vec))
                {
                    throw new InvalidDataException("C2 random vector is not matched.");
                }
            }
        }
Exemple #5
0
 public AckMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader = new RTMPBinaryReader(new MemoryStream(x.Body))) {
         SequenceNumber = reader.ReadUInt32();
     }
 }
Exemple #6
0
 public AbortMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader = new RTMPBinaryReader(new MemoryStream(x.Body))) {
         TargetChunkStream = (int)reader.ReadUInt32();
     }
 }
 public SetChunkSizeMessage(RTMPMessage x)
   : base(x)
 {
   using (var reader=new RTMPBinaryReader(new MemoryStream(x.Body))) {
     ChunkSize = (int)Math.Min(0x7FFFFFFL, reader.ReadUInt32());
   }
 }
 public AbortMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader=new RTMPBinaryReader(new MemoryStream(x.Body))) {
     TargetChunkStream = (int)reader.ReadUInt32();
       }
 }
Exemple #9
0
 public PingResponseMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader = new RTMPBinaryReader(new MemoryStream(x.Body))) {
         var type = (UserControlMessageType)reader.ReadUInt16();
         LocalTimestamp = reader.ReadUInt32();
     }
 }
Exemple #10
0
 public StreamIsRecordedMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader = new RTMPBinaryReader(new MemoryStream(x.Body))) {
         var type = (UserControlMessageType)reader.ReadUInt16();
         TargetStreamId = reader.ReadUInt32();
     }
 }
Exemple #11
0
 public UserControlMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader = new RTMPBinaryReader(new MemoryStream(x.Body))) {
         UserControlMessageType    = (UserControlMessageType)reader.ReadUInt16();
         UserControlMessagePayload = reader.ReadBytes(x.Body.Length - 2);
     }
 }
Exemple #12
0
 public SetPeerBandwidthMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader = new RTMPBinaryReader(new MemoryStream(x.Body))) {
         PeerBandwidth = reader.ReadUInt32();
         LimitType     = (PeerBandwidthLimitType)reader.ReadByte();
     }
 }
Exemple #13
0
 public SetBufferLengthMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader = new RTMPBinaryReader(new MemoryStream(x.Body))) {
         var type = (UserControlMessageType)reader.ReadUInt16();
         TargetStreamId = reader.ReadUInt32();
         BufferLength   = TimeSpan.FromMilliseconds(reader.ReadUInt32());
     }
 }
        private bool Handshake()
        {
            Logger.Debug("Handshake start");
            var rand = new Random();
            var c0   = Recv(1);

            Send(new byte[] { 0x03 });
            var s1vec = new byte[1528];

            rand.NextBytes(s1vec);
            Send(s => {
                using (var writer = new RTMPBinaryWriter(s)) {
                    writer.Write(0);
                    writer.Write(0);
                    writer.Write(s1vec);
                }
            });
            using (var reader = new RTMPBinaryReader(new MemoryStream(Recv(1536)))) {
                Send(s => {
                    using (var writer = new RTMPBinaryWriter(s)) {
                        writer.Write(reader.ReadInt32());
                        writer.Write(reader.ReadInt32());
                        writer.Write(reader.ReadBytes(1528));
                    }
                });
            }
            using (var reader = new RTMPBinaryReader(new MemoryStream(Recv(1536)))) {
                reader.ReadInt32();
                reader.ReadInt32();
                if (!s1vec.Equals(reader.ReadBytes(1528)))
                {
                    Logger.Debug("Handshake failed");
                    return(false);
                }
            }
            timer.Reset();
            timer.Start();
            Logger.Debug("Handshake succeeded");
            return(true);
        }
        private async Task HandshakeNew(RTMPBinaryReader c1reader, CancellationToken cancel_token)
        {
            var s1   = new byte[1536];
            var rand = new Random();

            rand.NextBytes(s1);
            //timestamp
            s1[0] = s1[1] = s1[2] = s1[3] = 0;
            //version
            s1[4] = 3;
            s1[5] = 5;
            s1[6] = 1;
            s1[7] = 1;
            s1    = SetServerHandshakeDigest1(s1, DigestPosition.First);
            await SendAsync(s1, cancel_token).ConfigureAwait(false);

            var c1    = c1reader.ReadBytes(1536);
            var c1pos = ValidateClientHandshakeDigest1(c1);

            if (c1pos == DigestPosition.Unknown)
            {
                throw new InvalidDataException("C1 digest is not matched.");
            }

            var s2 = SetServerHandshakeDigest2(c1, c1pos);

            await SendAsync(s2, cancel_token).ConfigureAwait(false);

            using (var c2reader = await RecvAsync(1536, cancel_token).ConfigureAwait(false)) {
                var c2 = c2reader.ReadBytes(1536);
                if (!ValidateClientHandshakeDigest2(c2, s1, DigestPosition.First))
                {
                    throw new InvalidDataException("C2 digest is not matched.");
                }
            }
        }
 public AckMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader=new RTMPBinaryReader(new MemoryStream(x.Body))) {
     SequenceNumber = reader.ReadUInt32();
       }
 }
        private async Task <bool> RecvMessage(Queue <RTMPMessage> messages, CancellationToken cancel_token)
        {
            var basic_header    = (await RecvStream(1, cancel_token).ConfigureAwait(false))[0];
            var chunk_stream_id = basic_header & 0x3F;

            if (chunk_stream_id == 0)
            {
                chunk_stream_id = (await RecvStream(1, cancel_token).ConfigureAwait(false))[0] + 64;
            }
            else if (chunk_stream_id == 1)
            {
                var buf = await RecvStream(2, cancel_token).ConfigureAwait(false);

                chunk_stream_id = (buf[1] * 256 | buf[0]) + 64;
            }

            RTMPMessageBuilder msg      = null;
            RTMPMessageBuilder last_msg = null;

            if (!lastMessages.TryGetValue(chunk_stream_id, out last_msg))
            {
                last_msg = RTMPMessageBuilder.NullPacket;
            }
            switch ((basic_header & 0xC0) >> 6)
            {
            case 0:
                using (var reader = new RTMPBinaryReader(await RecvStream(11, cancel_token).ConfigureAwait(false))) {
                    long timestamp   = reader.ReadUInt24();
                    var  body_length = reader.ReadUInt24();
                    var  type_id     = reader.ReadByte();
                    var  stream_id   = reader.ReadUInt32LE();
                    if (timestamp == 0xFFFFFF)
                    {
                        using (var ext_reader = new RTMPBinaryReader(await RecvStream(4, cancel_token).ConfigureAwait(false))) {
                            timestamp = ext_reader.ReadUInt32();
                        }
                    }
                    msg = new RTMPMessageBuilder(
                        last_msg,
                        timestamp,
                        type_id,
                        stream_id,
                        body_length);
                    lastMessages[chunk_stream_id] = msg;
                }
                break;

            case 1:
                using (var reader = new RTMPBinaryReader(await RecvStream(7, cancel_token).ConfigureAwait(false))) {
                    long timestamp_delta = reader.ReadUInt24();
                    var  body_length     = reader.ReadUInt24();
                    var  type_id         = reader.ReadByte();
                    if (timestamp_delta == 0xFFFFFF)
                    {
                        using (var ext_reader = new RTMPBinaryReader(await RecvStream(4, cancel_token).ConfigureAwait(false))) {
                            timestamp_delta = ext_reader.ReadUInt32();
                        }
                    }
                    msg = new RTMPMessageBuilder(
                        last_msg,
                        timestamp_delta,
                        type_id,
                        body_length);
                    lastMessages[chunk_stream_id] = msg;
                }
                break;

            case 2:
                using (var reader = new RTMPBinaryReader(await RecvStream(3, cancel_token).ConfigureAwait(false))) {
                    long timestamp_delta = reader.ReadUInt24();
                    if (timestamp_delta == 0xFFFFFF)
                    {
                        using (var ext_reader = new RTMPBinaryReader(await RecvStream(4, cancel_token).ConfigureAwait(false))) {
                            timestamp_delta = ext_reader.ReadUInt32();
                        }
                    }
                    msg = new RTMPMessageBuilder(last_msg, timestamp_delta);
                    lastMessages[chunk_stream_id] = msg;
                }
                break;

            case 3:
                msg = last_msg;
                if (msg.ReceivedLength >= msg.BodyLength)
                {
                    msg = new RTMPMessageBuilder(last_msg);
                    lastMessages[chunk_stream_id] = msg;
                }
                break;
            }

            msg.ReceivedLength += await RecvStream(
                msg.Body,
                msg.ReceivedLength,
                Math.Min(recvChunkSize, msg.BodyLength - msg.ReceivedLength),
                cancel_token).ConfigureAwait(false);

            if (msg.ReceivedLength >= msg.BodyLength)
            {
                messages.Enqueue(msg.ToMessage());
            }
            return(true); //TODO:接続エラー時はfalseを返す
        }
 public StreamIsRecordedMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader=new RTMPBinaryReader(new MemoryStream(x.Body))) {
       var type = (UserControlMessageType)reader.ReadUInt16();
       TargetStreamId = reader.ReadUInt32();
     }
 }
        private bool RecvMessage(Queue <RTMPMessage> messages)
        {
            var basic_header    = RecvStream(1)[0];
            var chunk_stream_id = basic_header & 0x3F;

            if (chunk_stream_id == 0)
            {
                chunk_stream_id = RecvStream(1)[0] + 64;
            }
            else if (chunk_stream_id == 1)
            {
                var buf = RecvStream(2);
                chunk_stream_id = (buf[1] * 256 | buf[0]) + 64;
            }

            RTMPMessageBuilder msg      = null;
            RTMPMessageBuilder last_msg = null;

            lastMessages.TryGetValue(chunk_stream_id, out last_msg);
            switch ((basic_header & 0xC0) >> 6)
            {
            case 0:
                using (var reader = new RTMPBinaryReader(new MemoryStream(RecvStream(11)))) {
                    long timestamp   = reader.ReadUInt24();
                    var  body_length = reader.ReadUInt24();
                    var  type_id     = reader.ReadByte();
                    var  stream_id   = reader.ReadUInt32LE();
                    if (timestamp == 0xFFFFFF)
                    {
                        using (var ext_reader = new RTMPBinaryReader(new MemoryStream(RecvStream(4)))) {
                            timestamp = ext_reader.ReadUInt32();
                        }
                    }
                    msg = new RTMPMessageBuilder(
                        last_msg,
                        timestamp,
                        type_id,
                        stream_id,
                        body_length);
                    lastMessages[chunk_stream_id] = msg;
                }
                break;

            case 1:
                using (var reader = new RTMPBinaryReader(new MemoryStream(RecvStream(7)))) {
                    long timestamp_delta = reader.ReadUInt24();
                    var  body_length     = reader.ReadUInt24();
                    var  type_id         = reader.ReadByte();
                    if (timestamp_delta == 0xFFFFFF)
                    {
                        using (var ext_reader = new RTMPBinaryReader(new MemoryStream(RecvStream(4)))) {
                            timestamp_delta = ext_reader.ReadUInt32();
                        }
                    }
                    msg = new RTMPMessageBuilder(
                        last_msg,
                        timestamp_delta,
                        type_id,
                        body_length);
                    lastMessages[chunk_stream_id] = msg;
                }
                break;

            case 2:
                using (var reader = new RTMPBinaryReader(new MemoryStream(RecvStream(3)))) {
                    long timestamp_delta = reader.ReadUInt24();
                    if (timestamp_delta == 0xFFFFFF)
                    {
                        using (var ext_reader = new RTMPBinaryReader(new MemoryStream(RecvStream(4)))) {
                            timestamp_delta = ext_reader.ReadUInt32();
                        }
                    }
                    msg = new RTMPMessageBuilder(last_msg, timestamp_delta);
                    lastMessages[chunk_stream_id] = msg;
                }
                break;

            case 3:
                msg = last_msg;
                if (msg.ReceivedLength >= msg.BodyLength)
                {
                    msg = new RTMPMessageBuilder(last_msg);
                    lastMessages[chunk_stream_id] = msg;
                }
                break;
            }

            msg.ReceivedLength += RecvStream(
                msg.Body,
                msg.ReceivedLength,
                Math.Min(recvChunkSize, msg.BodyLength - msg.ReceivedLength));
            if (msg.ReceivedLength >= msg.BodyLength)
            {
                messages.Enqueue(msg.ToMessage());
            }
            return(true); //TODO:接続エラー時はfalseを返す
        }
    private async Task<bool> RecvMessage(Queue<RTMPMessage> messages, CancellationToken cancel_token)
    {
      var basic_header = (await RecvStream(1, cancel_token))[0];
      var chunk_stream_id = basic_header & 0x3F;
      if (chunk_stream_id==0) {
        chunk_stream_id = (await RecvStream(1, cancel_token))[0] + 64;
      }
      else if (chunk_stream_id==1) {
        var buf = await RecvStream(2, cancel_token);
        chunk_stream_id = (buf[1]*256 | buf[0]) + 64;
      }

      RTMPMessageBuilder msg = null;
      RTMPMessageBuilder last_msg = null;
      if (!lastMessages.TryGetValue(chunk_stream_id, out last_msg)) {
        last_msg = RTMPMessageBuilder.NullPacket;
      }
      switch ((basic_header & 0xC0)>>6) {
      case 0:
        using (var reader=new RTMPBinaryReader(await RecvStream(11, cancel_token))) {
          long timestamp  = reader.ReadUInt24();
          var body_length = reader.ReadUInt24();
          var type_id     = reader.ReadByte();
          var stream_id   = reader.ReadUInt32LE();
          if (timestamp==0xFFFFFF) {
            using (var ext_reader=new RTMPBinaryReader(await RecvStream(4, cancel_token))) {
              timestamp = ext_reader.ReadUInt32();
            }
          }
          msg = new RTMPMessageBuilder(
            last_msg,
            timestamp,
            type_id,
            stream_id,
            body_length);
          lastMessages[chunk_stream_id] = msg;
        }
        break;
      case 1:
        using (var reader=new RTMPBinaryReader(await RecvStream(7, cancel_token))) {
          long timestamp_delta = reader.ReadUInt24();
          var body_length      = reader.ReadUInt24();
          var type_id          = reader.ReadByte();
          if (timestamp_delta==0xFFFFFF) {
            using (var ext_reader=new RTMPBinaryReader(await RecvStream(4, cancel_token))) {
              timestamp_delta = ext_reader.ReadUInt32();
            }
          }
          msg = new RTMPMessageBuilder(
            last_msg,
            timestamp_delta,
            type_id,
            body_length);
          lastMessages[chunk_stream_id] = msg;
        }
        break;
      case 2:
        using (var reader=new RTMPBinaryReader(await RecvStream(3, cancel_token))) {
          long timestamp_delta = reader.ReadUInt24();
          if (timestamp_delta==0xFFFFFF) {
            using (var ext_reader=new RTMPBinaryReader(await RecvStream(4, cancel_token))) {
              timestamp_delta = ext_reader.ReadUInt32();
            }
          }
          msg = new RTMPMessageBuilder(last_msg, timestamp_delta);
          lastMessages[chunk_stream_id] = msg;
        }
        break;
      case 3:
        msg = last_msg;
        if (msg.ReceivedLength>=msg.BodyLength) {
          msg = new RTMPMessageBuilder(last_msg);
          lastMessages[chunk_stream_id] = msg;
        }
        break;
      }

      msg.ReceivedLength += await RecvStream(
        msg.Body,
        msg.ReceivedLength,
        Math.Min(recvChunkSize, msg.BodyLength-msg.ReceivedLength),
        cancel_token);
      if (msg.ReceivedLength>=msg.BodyLength) {
        messages.Enqueue(msg.ToMessage());
      }
      return true; //TODO:接続エラー時はfalseを返す
    }
		protected async Task RecvStream(int len, Func<RTMPBinaryReader, Task> reader_action, CancellationToken cancel_token)
		{
			var buf = new byte[len];
			await RecvStream(buf, 0, len, cancel_token);
			using (var reader=new RTMPBinaryReader(new MemoryStream(buf))) {
				await reader_action.Invoke(reader);
			}
		}
        private bool RecvMessage(Queue<RTMPMessage> messages)
        {
            var basic_header = RecvStream(1)[0];
              var chunk_stream_id = basic_header & 0x3F;
              if (chunk_stream_id==0) {
            chunk_stream_id = RecvStream(1)[0] + 64;
              }
              else if (chunk_stream_id==1) {
            var buf = RecvStream(2);
            chunk_stream_id = (buf[1]*256 | buf[0]) + 64;
              }

              RTMPMessageBuilder msg = null;
              RTMPMessageBuilder last_msg = null;
              lastMessages.TryGetValue(chunk_stream_id, out last_msg);
              switch ((basic_header & 0xC0)>>6) {
              case 0:
            using (var reader=new RTMPBinaryReader(new MemoryStream(RecvStream(11)))) {
              long timestamp  = reader.ReadUInt24();
              var body_length = reader.ReadUInt24();
              var type_id     = reader.ReadByte();
              var stream_id   = reader.ReadUInt32LE();
              if (timestamp==0xFFFFFF) {
            using (var ext_reader=new RTMPBinaryReader(new MemoryStream(RecvStream(4)))) {
              timestamp = ext_reader.ReadUInt32();
            }
              }
              msg = new RTMPMessageBuilder(
            last_msg,
            timestamp,
            type_id,
            stream_id,
            body_length);
              lastMessages[chunk_stream_id] = msg;
            }
            break;
              case 1:
            using (var reader=new RTMPBinaryReader(new MemoryStream(RecvStream(7)))) {
              long timestamp_delta = reader.ReadUInt24();
              var body_length      = reader.ReadUInt24();
              var type_id          = reader.ReadByte();
              if (timestamp_delta==0xFFFFFF) {
            using (var ext_reader=new RTMPBinaryReader(new MemoryStream(RecvStream(4)))) {
              timestamp_delta = ext_reader.ReadUInt32();
            }
              }
              msg = new RTMPMessageBuilder(
            last_msg,
            timestamp_delta,
            type_id,
            body_length);
              lastMessages[chunk_stream_id] = msg;
            }
            break;
              case 2:
            using (var reader=new RTMPBinaryReader(new MemoryStream(RecvStream(3)))) {
              long timestamp_delta = reader.ReadUInt24();
              if (timestamp_delta==0xFFFFFF) {
            using (var ext_reader=new RTMPBinaryReader(new MemoryStream(RecvStream(4)))) {
              timestamp_delta = ext_reader.ReadUInt32();
            }
              }
              msg = new RTMPMessageBuilder(last_msg, timestamp_delta);
              lastMessages[chunk_stream_id] = msg;
            }
            break;
              case 3:
            msg = last_msg;
            if (msg.ReceivedLength>=msg.BodyLength) {
              msg = new RTMPMessageBuilder(last_msg);
            }
            break;
              }

              msg.ReceivedLength += RecvStream(
            msg.Body,
            msg.ReceivedLength,
            Math.Min(recvChunkSize, msg.BodyLength-msg.ReceivedLength));
              if (msg.ReceivedLength>=msg.BodyLength) {
            messages.Enqueue(msg.ToMessage());
              }
              return true; //TODO:接続エラー時はfalseを返す
        }
 public PingResponseMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader=new RTMPBinaryReader(new MemoryStream(x.Body))) {
       var type = (UserControlMessageType)reader.ReadUInt16();
       LocalTimestamp = reader.ReadUInt32();
     }
 }
 public AggregateMessage(RTMPMessage x)
     : base(x)
 {
     var messages = new List<RTMPMessage>();
       using (var reader=new RTMPBinaryReader(new MemoryStream(x.Body))) {
     while (reader.BaseStream.Position<reader.BaseStream.Length) {
       var message_type = (RTMPMessageType)reader.ReadByte();
       var length       = reader.ReadUInt24();
       var timestamp    = reader.ReadUInt32();
       var stream_id    = reader.ReadUInt24();
       var body         = reader.ReadBytes(length);
       var msg = new RTMPMessage(
     message_type,
     timestamp + x.Timestamp,
     x.StreamId,
     body);
       var prevlen = reader.ReadUInt32();
       if (prevlen==body.Length+11) {
     messages.Add(msg);
       }
     }
       }
 }
 public SetWindowSizeMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader=new RTMPBinaryReader(new MemoryStream(x.Body))) {
     WindowSize = reader.ReadUInt32();
       }
 }
 public SetPeerBandwidthMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader=new RTMPBinaryReader(new MemoryStream(x.Body))) {
     PeerBandwidth = reader.ReadUInt32();
     LimitType = (PeerBandwidthLimitType)reader.ReadByte();
       }
 }
		private async Task HandshakeNew(RTMPBinaryReader c1reader, CancellationToken cancel_token)
		{
			var s1 = new byte[1536];
			var rand = new Random();
			rand.NextBytes(s1);
			//timestamp
			s1[0] = s1[1] = s1[2] = s1[3] = 0;
			//version
			s1[4] = 3;
			s1[5] = 5;
			s1[6] = 1;
			s1[7] = 1;
			s1 = SetServerHandshakeDigest1(s1, DigestPosition.First);
			await Send(s1, cancel_token);

			var c1 = c1reader.ReadBytes(1536);
			var c1pos = ValidateClientHandshakeDigest1(c1);
			if (c1pos==DigestPosition.Unknown) {
				throw new InvalidDataException("C1 digest is not matched.");
			}

			var s2 = SetServerHandshakeDigest2(c1, c1pos);
			await Send(s2, cancel_token);

			var c2reader = await Recv(1536, cancel_token);
			var c2 = c2reader.ReadBytes(1536);
			if (!ValidateClientHandshakeDigest2(c2, s1, DigestPosition.First)) {
				throw new InvalidDataException("C2 digest is not matched.");
			}
		}
 public UserControlMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader=new RTMPBinaryReader(new MemoryStream(x.Body))) {
     UserControlMessageType = (UserControlMessageType)reader.ReadUInt16();
     UserControlMessagePayload = reader.ReadBytes(x.Body.Length-2);
       }
 }
		private async Task HandshakeOld(RTMPBinaryReader c1reader, CancellationToken cancel_token)
		{
			var s1vec = new byte[1528];
			var rand = new Random();
			rand.NextBytes(s1vec);
			await Send(writer => {
				writer.Write(0);
				writer.Write(0);
				writer.Write(s1vec);
			}, cancel_token);

			var c1time = c1reader.ReadInt32();
			var c1ver  = c1reader.ReadInt32();
			var c1vec  = c1reader.ReadBytes(1528);
			await Send(writer => {
				writer.Write(c1time);
				writer.Write(c1ver);
				writer.Write(c1vec);
			}, cancel_token);

			await Recv(1536, reader => {
				var c2time = reader.ReadInt32();
				var c2zero = reader.ReadInt32();
				var c2vec = reader.ReadBytes(1528);
				if (!s1vec.SequenceEqual(c2vec)) {
					throw new InvalidDataException("C2 random vector is not matched.");
				}
			}, cancel_token);
		}
 public SetBufferLengthMessage(RTMPMessage x)
     : base(x)
 {
     using (var reader=new RTMPBinaryReader(new MemoryStream(x.Body))) {
       var type = (UserControlMessageType)reader.ReadUInt16();
       TargetStreamId = reader.ReadUInt32();
       BufferLength   = TimeSpan.FromMilliseconds(reader.ReadUInt32());
     }
 }
 private bool Handshake()
 {
     Logger.Debug("Handshake start");
       var rand = new Random();
       var c0 = Recv(1);
       Send(new byte[] { 0x03 });
       var s1vec = new byte[1528];
       rand.NextBytes(s1vec);
       Send(s => {
     using (var writer=new RTMPBinaryWriter(s)) {
       writer.Write(0);
       writer.Write(0);
       writer.Write(s1vec);
     }
       });
       using (var reader=new RTMPBinaryReader(new MemoryStream(Recv(1536)))) {
     Send(s => {
       using (var writer=new RTMPBinaryWriter(s)) {
     writer.Write(reader.ReadInt32());
     writer.Write(reader.ReadInt32());
     writer.Write(reader.ReadBytes(1528));
       }
     });
       }
       using (var reader=new RTMPBinaryReader(new MemoryStream(Recv(1536)))) {
     reader.ReadInt32();
     reader.ReadInt32();
     if (!s1vec.Equals(reader.ReadBytes(1528))) {
       Logger.Debug("Handshake failed");
       return false;
     }
       }
       timer.Reset();
       timer.Start();
       Logger.Debug("Handshake succeeded");
       return true;
 }