public void Do(BinaryWriter bw, BinaryReader br) { PrepareC0(); SendC0(bw); PrepareC1(); SendC1(bw); ReceiveS0(br); ReceiveS1(br); ReceiveS2(br); PrepareC2(); SendC2(bw); }
public RTMPConnection(IPAddress address, int port, int timeoutMilliseconds = 2000) { TcpClientWithTimeout tcpClient = new TcpClientWithTimeout(new IPEndPoint(address, port)); tcpClient.Connect(timeoutMilliseconds); InternalTcpClient = tcpClient.InternalClient; Counter = new CountingStream(InternalTcpClient.GetStream()); InternalBinaryReader = new BinaryReader(Counter); InternalBinaryWriter = new BinaryWriter(Counter); IncomingChunkSize = 128; OutgoingChunkSize = 128; readerThread = new Thread(reader_run); readerThread.IsBackground = true; readerThread.Start(); }
protected virtual void SendC0(BinaryWriter bw) { bw.Write(C0); // C0 = Version of protocol }
protected virtual void SendC2(BinaryWriter bw) { bw.Write(C2); // C2 (copy of S1) }
public void Send(BinaryWriter bw) { Header.Send(bw); Body.Send(bw); }
protected virtual void SendC1(BinaryWriter bw) { bw.Write(C1); // C1 is some random garbage (usually) bw.Flush(); }
private void SendMessageTypeID(BinaryWriter bw) { bw.Write((byte)MessageTypeID); }
private void SendTimestamp(BinaryWriter bw) { extendedTimeStamp = Timestamp >= 0xFFFFFF; // extended timestamp, 4 bytes byte[] bytes = new byte[3]; if (!extendedTimeStamp) { bytes[0] = (byte)(Timestamp >> 16); bytes[1] = (byte)(Timestamp >> 8); bytes[2] = (byte)Timestamp; } else { //send 0xFFFFFF bytes[0] = 0xFF; bytes[1] = 0xFF; bytes[2] = 0xFF; } bw.Write(bytes); }
private void SendMessageStreamID(BinaryWriter bw) { bw.OutputEndianness = Endianness.LittleEndian; bw.Write(MessageStreamID); bw.OutputEndianness = Endianness.BigEndian; }
private void SendMessageLength(BinaryWriter bw) { byte[] bytes = new byte[3]; int msgLen = MessageLength; bytes[0] = (byte)(msgLen >> 16); bytes[1] = (byte)(msgLen >> 8); bytes[2] = (byte)msgLen; bw.Write(bytes); }
private void SendFormatAndChunkStreamID(BinaryWriter bw) { byte fmt = (byte)((int)Format << 6); int chunkStreamId = (int)ChunkStreamID; if (chunkStreamId > 1 && chunkStreamId < 64) { //just put the cs_id over it fmt |= (byte)chunkStreamId; bw.Write(fmt); } else if (chunkStreamId > 63 && chunkStreamId < 320) { //1 byte extension, the cs_id is 0, fmt stays as it is byte cs_id = (byte)(chunkStreamId - 64); bw.Write(fmt); bw.Write(cs_id); } else if (chunkStreamId > 319 && chunkStreamId < 65600) { //2 byte extension, the cs_id is 1 fmt |= (byte)1; /*id = ((the thirdbyte)*256 + the second byte + 64 *id -64 = third*256 + second */ int cs_id = chunkStreamId - 64; byte cs_id2 = (byte)(cs_id & 0xFF); byte cs_id3 = (byte)(cs_id / 256); bw.Write(fmt); bw.Write(cs_id2); bw.Write(cs_id3); } else { throw new NotSupportedException("only chunk stream ids from 2 to 65599 are supported (0 and 1 are reserved[and are calculated automatically], while 2 is a special stream for 'low level messages')"); } }
private void SendExtendedTimestamp(BinaryWriter bw) { if (extendedTimeStamp) { byte[] bytes = new byte[4]; bytes[0] = (byte)(Timestamp >> 24); bytes[1] = (byte)(Timestamp >> 16); bytes[2] = (byte)(Timestamp >> 8); bytes[3] = (byte)Timestamp; bw.Write(bytes); } }
public void Send(BinaryWriter bw) { SendFormatAndChunkStreamID(bw); switch (Format) { case RTMPMessageFormat.BasicHeader_1: break; case RTMPMessageFormat.BasicHeaderAndTime_4: SendTimestamp(bw); SendExtendedTimestamp(bw); break; case RTMPMessageFormat.NoMessageId_8: SendTimestamp(bw); SendMessageLength(bw); SendMessageTypeID(bw); SendExtendedTimestamp(bw); break; case RTMPMessageFormat.FullHeader_12: SendTimestamp(bw); SendMessageLength(bw); SendMessageTypeID(bw); SendMessageStreamID(bw); SendExtendedTimestamp(bw); break; } }