/// <summary> /// expect packet from transport. /// </summary> /// <param name="buffer"> /// a BytesBuffer object that contains the received data from endpoint. /// </param> /// <param name="decoder"> /// a DecodePacketCallback delegate that is used to decode packet from buffer. /// </param> /// <param name="endpoint"> /// an object that specifies the endpoint for decoder.<para/> /// remember: this endpoint must be the endpoint that is returned to the user, /// that is the endpoint return by Connect(). /// </param> /// <param name="timeout"> /// a TimeSpan object that indicates the timeout to expect event. /// </param> /// <param name="packetCache"> /// a list that contains the stackpackets. /// </param> /// <returns> /// a StackPacket object that specifies the received packet. /// </returns> public static StackPacket Visit( BytesBuffer buffer, DecodePacketCallback decoder, object endpoint, TimeSpan timeout, SyncFilterQueue <StackPacket> packetCache) { // get the packet in packet list. if (packetCache.Count > 0) { return(Utility.GetOne <StackPacket>(packetCache, null)); } // the consumed length of decoder. int consumedLength = 0; // decode packet, return null or at least one packet. StackPacket[] packets = ExpectMultiPacketsVisitor.Visit( buffer, decoder, endpoint, timeout, out consumedLength); // packet is null, buffer is closed, no packet will come. if (packets == null) { return(null); } // if packet arrived, add to packet list, and return the first. foreach (StackPacket packet in packets) { packetCache.Enqueue(packet); } return(Utility.GetOne <StackPacket>(packetCache, null)); }
/// <summary> /// Constructor. Initialize member variables. /// </summary> /// <param name="transportConfig">Provides the transport parameters.</param> /// <param name="decodePacketCallback">Callback of decoding packet.</param> /// <param name="certificate">X509 certificate.</param> public RdpbcgrServerTransportStack( RdpbcgrServer rdpbcgrServer, RdpcbgrServerTransportConfig transportConfig, DecodePacketCallback decodePacketCallback, X509Certificate2 certificate) { this.rdpbcgrServer = rdpbcgrServer; this.config = transportConfig; if (this.config == null) { throw new System.InvalidCastException("TcpServerTransport needs SocketTransportConfig."); } this.decoder = decodePacketCallback; this.packetQueue = new QueueManager(); this.listenSock = new Socket(transportConfig.LocalIpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); this.listenSock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); this.streamType = transportConfig.StreamType; IPEndPoint endPoint = new IPEndPoint(config.LocalIpAddress, config.LocalIpPort); this.listenSock.Bind(endPoint); this.listenSock.Listen(config.MaxConnections); this.acceptThread = new Thread(new ThreadStart(AcceptLoop)); this.receivingStreams = new Dictionary <Socket, RdpbcgrReceiveThread>(); this.cert = certificate; }
/// <summary> /// Create a new thread to receive the data from remote host. /// </summary> /// <param name="packetQueueManager">Store all event packets generated in receiving loop.</param> /// <param name="decodePacketCallback">Callback of packet decode.</param> /// <param name="stream">The stream used to receive data.</param> /// <param name="bufferSize">Buffer size used in receiving data.</param> public RdpbcgrReceiveThread( object endPoint, QueueManager packetQueueManager, DecodePacketCallback decodePacketCallback, Stream stream, int bufferSize, RdpbcgrServer rdpbcgrServer) { if (packetQueueManager == null) { throw new ArgumentNullException("packetQueueManager"); } if (decodePacketCallback == null) { throw new ArgumentNullException("decodePacketCallback"); } // Initialize variable. this.endPointIdentity = endPoint; this.packetQueue = packetQueueManager; this.decoder = decodePacketCallback; this.receiveStream = stream; this.maxBufferSize = bufferSize; this.rdpbcgrServer = rdpbcgrServer; this.receivingThread = new Thread((new ThreadStart(ReceiveLoop))); }
/// <summary> /// Constructor. Initialize member variables. /// </summary> /// <param name="transportConfig">Provides the transport parameters.</param> /// <param name="decodePacketCallback">Callback of decoding packet.</param> public RdpbcgrServerTransportStack( RdpbcgrServer rdpbcgrServer, RdpcbgrServerTransportConfig transportConfig, DecodePacketCallback decodePacketCallback) { this.rdpbcgrServer = rdpbcgrServer; this.config = transportConfig; if (this.config == null) { throw new System.InvalidCastException("TcpServerTransport needs SocketTransportConfig."); } this.decoder = decodePacketCallback; this.packetQueue = new QueueManager(); this.receivingStreams = new Dictionary <Socket, RdpbcgrReceiveThread>(); }
/// <summary> /// consturctor. /// </summary> /// <param name="transportConfig"> /// a TransportConfig object that contains the config. /// </param> /// <param name="decodePacketCallback"> /// a DecodePacketCallback delegate that is used to decode the packet from bytes. /// </param> /// <exception cref="ArgumentException"> /// thrown when transportConfig is not StreamConfig /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when transportConfig is null. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when decodePacketCallback is null. /// </exception> public RdpbcgrClientTransportStack(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback) { if (transportConfig == null) { throw new ArgumentNullException("transportConfig"); } if (decodePacketCallback == null) { throw new ArgumentNullException("decodePacketCallback"); } this.UpdateConfig(transportConfig); buffer = new List <byte>(); this.eventQueue = new SyncFilterQueue <TransportEvent>(); this.packetCache = new SyncFilterQueue <StackPacket>(); this.decoder = decodePacketCallback; }
/// <summary> /// expect packet from transport. /// </summary> /// <param name="buffer"> /// a BytesBuffer object that contains the received data from endpoint. /// </param> /// <param name="decoder"> /// a DecodePacketCallback delegate that is used to decode packet from buffer. /// </param> /// <param name="endpoint"> /// an object that specifies the endpoint for decoder.<para/> /// remember: this endpoint is the identity endpoint of tcp/netbios connection, /// that is the remote endpoint of connection. /// </param> /// <param name="timeout"> /// a TimeSpan object that indicates the timeout to expect event. /// </param> /// <param name="consumedLength"> /// return an int value that specifies the consumed length. /// </param> /// <returns> /// a StackPacket object that specifies the received packet. /// </returns> public static StackPacket[] Visit( BytesBuffer buffer, DecodePacketCallback decoder, object endpoint, TimeSpan timeout, out int consumedLength) { bool bufferClosed; // get all data in buffer, at-least one byte. byte[] data = buffer.Read(timeout, BytesBuffer.MaxCount, 0, out bufferClosed); // the end time for operation. DateTime endTime = DateTime.Now + timeout; while (true) { // decode packets using data in buffer. int expectedLength = 0; // decode data. if (data.Length > 0) { StackPacket[] packets = decoder(endpoint, data, out consumedLength, out expectedLength); buffer.Remove(consumedLength); // if packet arrived, add to packet list, and return the first. if (packets != null && packets.Length > 0) { return(packets); } } // if buffer is closed, no data will come, return null. if (bufferClosed) { consumedLength = 0; return(null); } // wait for the next data coming. data = buffer.Read(endTime - DateTime.Now, BytesBuffer.MaxCount, data.Length, out bufferClosed); } }
/// <summary> /// consturctor. /// </summary> /// <param name="transportConfig"> /// a TransportConfig object that contains the config. /// </param> /// <param name="decodePacketCallback"> /// a DecodePacketCallback delegate that is used to decode the packet from bytes. /// </param> /// <exception cref="ArgumentException"> /// thrown when transportConfig is not StreamConfig /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when transportConfig is null. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when decodePacketCallback is null. /// </exception> public StreamTransport(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback) { if (transportConfig == null) { throw new ArgumentNullException("transportConfig"); } if (decodePacketCallback == null) { throw new ArgumentNullException("decodePacketCallback"); } this.UpdateConfig(transportConfig); this.buffer = new BytesBuffer(); this.eventQueue = new SyncFilterQueue <TransportEvent>(); this.packetCache = new SyncFilterQueue <StackPacket>(); this.decoder = decodePacketCallback; }
/// <summary> /// constructor /// </summary> /// <param name="transportConfig"> /// a TransportConfig object that contains the config. /// </param> /// <param name="decodePacketCallback"> /// a DecodePacketCallback delegate that is used to decode the packet from bytes. /// </param> /// <exception cref="ArgumentException"> /// thrown when transportConfig is not SocketTransportConfig /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when transportConfig is null. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when decodePacketCallback is null. /// </exception> public UdpClientTransport(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback) { if (transportConfig == null) { throw new ArgumentNullException("transportConfig"); } if (decodePacketCallback == null) { throw new ArgumentNullException("decodePacketCallback"); } this.UpdateConfig(transportConfig); this.eventQueue = new SyncFilterQueue <TransportEvent>(); this.buffer = new SyncFilterQueue <UdpReceivedBytes>(); this.packetCache = new SyncFilterQueue <IPEndPointStackPacket>(); this.decoder = decodePacketCallback; }
/// <summary> /// consturctor. /// </summary> /// <param name="transportConfig"> /// a TransportConfig object that contains the config. /// </param> /// <param name="decodePacketCallback"> /// a DecodePacketCallback delegate that is used to decode the packet from bytes. /// </param> /// <exception cref="ArgumentException"> /// thrown when transportConfig is not StreamConfig /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when transportConfig is null. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when decodePacketCallback is null. /// </exception> public StreamTransport(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback) { if (transportConfig == null) { throw new ArgumentNullException("transportConfig"); } if (decodePacketCallback == null) { throw new ArgumentNullException("decodePacketCallback"); } this.UpdateConfig(transportConfig); this.buffer = new BytesBuffer(); this.eventQueue = new SyncFilterQueue<TransportEvent>(); this.packetCache = new SyncFilterQueue<StackPacket>(); this.decoder = decodePacketCallback; }
/// <summary> /// consturctor. /// </summary> /// <param name="transportConfig"> /// a TransportConfig object that contains the config. /// </param> /// <param name="decodePacketCallback"> /// a DecodePacketCallback delegate that is used to decode the packet from bytes. /// </param> /// <exception cref="ArgumentException"> /// thrown when transportConfig is not SocketTransportConfig /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when transportConfig is null. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when decodePacketCallback is null. /// </exception> public TcpServerTransport(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback) { if (transportConfig == null) { throw new ArgumentNullException("transportConfig"); } if (decodePacketCallback == null) { throw new ArgumentNullException("decodePacketCallback"); } this.UpdateConfig(transportConfig); this.decoder = decodePacketCallback; this.listeners = new Dictionary<IPEndPoint, TcpServerListener>(); this.connections = new Dictionary<IPEndPoint, TcpServerConnection>(); this.eventQueue = new SyncFilterQueue<TransportEvent>(); this.sequence = new DataSequence(); this.packetCache = new SyncFilterQueue<IPEndPointStackPacket>(); }
/// <summary> /// Constructor. Initialize member variables. /// </summary> /// <param name="transportConfig">Provides the transport parameters.</param> /// <param name="decodePacketCallback">Callback of decoding packet.</param> /// <param name="certificate">X509 certificate.</param> public RdpbcgrServerTransportStack( RdpbcgrServer rdpbcgrServer, RdpcbgrServerTransportConfig transportConfig, DecodePacketCallback decodePacketCallback, X509Certificate2 certificate) { this.rdpbcgrServer = rdpbcgrServer; this.config = transportConfig; if (this.config == null) { throw new System.InvalidCastException("TcpServerTransport needs SocketTransportConfig."); } this.decoder = decodePacketCallback; this.packetQueue = new QueueManager(); this.listenSock = new Socket(transportConfig.LocalIpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); this.streamType = transportConfig.StreamType; IPEndPoint endPoint = new IPEndPoint(config.LocalIpAddress, config.LocalIpPort); this.listenSock.Bind(endPoint); this.listenSock.Listen(config.MaxConnections); this.acceptThread = new Thread(new ThreadStart(AcceptLoop)); this.receivingStreams = new Dictionary<Socket, RdpbcgrReceiveThread>(); this.cert = certificate; }
/// <summary> /// constructor /// </summary> /// <param name="transportConfig"> /// a TransportConfig object that contains the config. /// </param> /// <param name="decodePacketCallback"> /// a DecodePacketCallback delegate that is used to decode the packet from bytes. /// </param> /// <exception cref="ArgumentException"> /// thrown when transportConfig is not SocketTransportConfig /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when transportConfig is null. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when decodePacketCallback is null. /// </exception> public UdpServerTransport(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback) { if (transportConfig == null) { throw new ArgumentNullException("transportConfig"); } if (decodePacketCallback == null) { throw new ArgumentNullException("decodePacketCallback"); } this.UpdateConfig(transportConfig); this.listeners = new Dictionary<IPEndPoint, UdpServerListener>(); this.eventQueue = new SyncFilterQueue<TransportEvent>(); this.packetCache = new SyncFilterQueue<IPEndPointStackPacket>(); this.buffer = new SyncFilterQueue<UdpReceivedBytes>(); this.decoder = decodePacketCallback; }
/// <summary> /// Constructor. To create the instance of transport specified in the transportConfig. /// </summary> /// <param name="transportConfig"> /// a TransportConfig object that specifies the transport type and parameters. /// </param> /// <param name="decodePacketCallback"> /// a DecodePacketCallback delegate that is used to decode the packet from bytes. /// </param> /// <exception cref="InvalidOperationException"> /// thrown when StackTransportType is invalid. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when Role is invalid, for transport type is Tcp, it must be Server or Client. /// </exception> /// <exception cref="InvalidOperationException"> /// thrown when Role is invalid, for transport type is Netbios, it must be Server or Client. /// </exception> public TransportStack(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback) { switch (transportConfig.Type) { case StackTransportType.Tcp: if (transportConfig.Role == Role.Client) { this.transport = new TcpClientTransport(transportConfig, decodePacketCallback); } else if (transportConfig.Role == Role.Server) { this.transport = new TcpServerTransport(transportConfig, decodePacketCallback); } else { throw new InvalidOperationException( "Role is invalid, for transport type is Tcp, it must be Server or Client."); } break; case StackTransportType.Netbios: if (transportConfig.Role == Role.Client) { this.transport = new NetbiosClientTransport(transportConfig, decodePacketCallback); } else if (transportConfig.Role == Role.Server) { this.transport = new NetbiosServerTransport(transportConfig, decodePacketCallback); } else { throw new InvalidOperationException( "Role is invalid, for transport type is Netbios, it must be Server or Client."); } break; case StackTransportType.Stream: this.transport = new StreamTransport(transportConfig, decodePacketCallback); break; case StackTransportType.Udp: if (transportConfig.Role == Role.Server) { this.transport = new UdpServerTransport(transportConfig, decodePacketCallback); } // all other role are equals to Client. else { this.transport = new UdpClientTransport(transportConfig, decodePacketCallback); } break; default: throw new InvalidOperationException("StackTransportType is invalid."); } }
/// <summary> /// expect packet from transport. /// </summary> /// <param name="buffer"> /// a BytesBuffer object that contains the received data from endpoint. /// </param> /// <param name="decoder"> /// a DecodePacketCallback delegate that is used to decode packet from buffer. /// </param> /// <param name="endpoint"> /// an object that specifies the endpoint for decoder.<para/> /// remember: this endpoint must be the endpoint that is returned to the user, /// that is the endpoint return by Connect(). /// </param> /// <param name="timeout"> /// a TimeSpan object that indicates the timeout to expect event. /// </param> /// <param name="packetCache"> /// a list that contains the stackpackets. /// </param> /// <returns> /// a StackPacket object that specifies the received packet. /// </returns> public static StackPacket Visit( BytesBuffer buffer, DecodePacketCallback decoder, object endpoint, TimeSpan timeout, SyncFilterQueue<StackPacket> packetCache) { // get the packet in packet list. if (packetCache.Count > 0) { return Utility.GetOne<StackPacket>(packetCache, null); } // the consumed length of decoder. int consumedLength = 0; // decode packet, return null or at least one packet. StackPacket[] packets = ExpectMultiPacketsVisitor.Visit( buffer, decoder, endpoint, timeout, out consumedLength); // packet is null, buffer is closed, no packet will come. if (packets == null) { return null; } // if packet arrived, add to packet list, and return the first. foreach (StackPacket packet in packets) { packetCache.Enqueue(packet); } return Utility.GetOne<StackPacket>(packetCache, null); }
/// <summary> /// consturctor. /// </summary> /// <param name="transportConfig"> /// a TransportConfig object that contains the config. /// </param> /// <param name="decodePacketCallback"> /// a DecodePacketCallback delegate that is used to decode the packet from bytes. /// </param> /// <exception cref="ArgumentException"> /// thrown when transportConfig is not StreamConfig /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when transportConfig is null. /// </exception> /// <exception cref="ArgumentNullException"> /// thrown when decodePacketCallback is null. /// </exception> public RdpbcgrClientTransportStack(TransportConfig transportConfig, DecodePacketCallback decodePacketCallback) { if (transportConfig == null) { throw new ArgumentNullException("transportConfig"); } if (decodePacketCallback == null) { throw new ArgumentNullException("decodePacketCallback"); } this.UpdateConfig(transportConfig); buffer = new List<byte>(); this.eventQueue = new SyncFilterQueue<TransportEvent>(); this.packetCache = new SyncFilterQueue<StackPacket>(); this.decoder = decodePacketCallback; }
/// <summary> /// expect packet from transport. /// </summary> /// <param name="buffer"> /// a BytesBuffer object that contains the received data from endpoint. /// </param> /// <param name="decoder"> /// a DecodePacketCallback delegate that is used to decode packet from buffer. /// </param> /// <param name="endpoint"> /// an object that specifies the endpoint for decoder.<para/> /// remember: this endpoint is the identity endpoint of tcp/netbios connection, /// that is the remote endpoint of connection. /// </param> /// <param name="timeout"> /// a TimeSpan object that indicates the timeout to expect event. /// </param> /// <param name="consumedLength"> /// return an int value that specifies the consumed length. /// </param> /// <returns> /// a StackPacket object that specifies the received packet. /// </returns> public static StackPacket[] Visit( BytesBuffer buffer, DecodePacketCallback decoder, object endpoint, TimeSpan timeout, out int consumedLength) { bool bufferClosed; // get all data in buffer, at-least one byte. byte[] data = buffer.Read(timeout, BytesBuffer.MaxCount, 0, out bufferClosed); // the end time for operation. DateTime endTime = DateTime.Now + timeout; while (true) { // decode packets using data in buffer. int expectedLength = 0; // decode data. if (data.Length > 0) { StackPacket[] packets = decoder(endpoint, data, out consumedLength, out expectedLength); buffer.Remove(consumedLength); // if packet arrived, add to packet list, and return the first. if (packets != null && packets.Length > 0) { return packets; } } // if buffer is closed, no data will come, return null. if (bufferClosed) { consumedLength = 0; return null; } // wait for the next data coming. data = buffer.Read(endTime - DateTime.Now, BytesBuffer.MaxCount, data.Length, out bufferClosed); } }