/// <summary>
        /// The is the socket server listening thread. Creats a new client and
        /// starts a heartbeat client thread to implement the ping/pong protocol.
        /// </summary>
        protected void ListenForClients()
        {
            mRunning = true;

            try
            {
                while (mRunning)
                {
                    //blocks until a client has connected to the server
                    TcpClientProvider client = _tcpListener.AcceptTcpClient();

                    //create a thread to handle communication
                    //with connected client
                    Thread clientThread = new Thread(new ParameterizedThreadStart(HeartbeatClient));
                    clientThread.Start(client);

                    clientThread.Join();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Execption occurred waiting for connection: " + e.Message);
            }

            finally
            {
                mRunning = false;
                _tcpListener.Stop();
            }
        }
예제 #2
0
 public WSClientProvider(int bufferSize = 4096, int blocks = 8)
 {
     clientProvider = new TcpClientProvider(bufferSize, blocks);
     clientProvider.DisconnectedCallback   = new OnDisconnectedHandler(DisconnectedHandler);
     clientProvider.ReceivedOffsetCallback = new OnReceivedSegmentHandler(ReceivedHanlder);
     clientProvider.SentCallback           = new OnSentHandler(SentHandler);
 }
예제 #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TcpSimpleClient"/> class.
 /// </summary>
 /// <param name="connectString">Connect string of the <see cref="TcpSimpleClient"/>. See <see cref="DefaultConnectionString"/> for format.</param>
 public TcpSimpleClient(string connectString) : base(TransportProtocol.Tcp, connectString)
 {
     m_tcpClient          = new TcpClientProvider();
     PayloadAware         = DefaultPayloadAware;
     m_payloadMarker      = Payload.DefaultMarker;
     m_payloadEndianOrder = EndianOrder.LittleEndian;
     NoDelay = DefaultNoDelay;
 }
예제 #4
0
        public NetClientProvider(NetProviderType netProviderType)
        {
            NetProviderType             = netProviderType;
            this.bufferSizeByConnection = 4096;
            this.maxConcurrentNumber    = 8;

            if (netProviderType == NetProviderType.Tcp)
            {
                tcpClientProvider = new TcpClientProvider(bufferSizeByConnection, maxConcurrentNumber);
            }
            else if (netProviderType == NetProviderType.Udp)
            {
                udpClientProvider = new UdpClientProvider(bufferSizeByConnection, maxConcurrentNumber);
            }
        }
예제 #5
0
        public NetClientProvider(ProviderType netProviderType = ProviderType.Tcp,
                                 int bufferSizeByConnection   = 4096, int maxNumberOfConnections = 8)
        {
            NetProviderType             = netProviderType;
            this.bufferSizeByConnection = bufferSizeByConnection;
            this.maxNumberOfConnections = maxNumberOfConnections;

            if (netProviderType == ProviderType.Tcp)
            {
                tcpClientProvider = new TcpClientProvider(bufferSizeByConnection, maxNumberOfConnections);
            }
            else if (netProviderType == ProviderType.Udp)
            {
                udpClientProvider = new UdpClientProvider();
            }
        }
        /// <summary>
        /// The heartbeat thread for a client. This thread receives data from a client,
        /// closes the socket when it fails, and handles communication timeouts when
        /// the client does not send a heartbeat within 2x the heartbeat frequency.
        ///
        /// When the heartbeat is not received, the client is assumed to be unresponsive
        /// and the connection is closed. Waits for one ping to be received before
        /// enforcing the timeout.
        /// </summary>
        /// <param name="client">The client we are communicating with.</param>
        protected void HeartbeatClient(object obj)
        {
            mActiveClients.AddCount();
            TcpClientProvider client       = (TcpClientProvider)obj;
            Stream            clientStream = client.GetStream();

            lock (mClients)
            {
                mClients.Add(clientStream);
            }

            // Send the current state and replay commands to new clients
            SendAllTo(clientStream);
            foreach (Tuple <DeviceCommand, string> tuple in _commandsToSendOnConnect)
            {
                _sendCommandToClient(clientStream, tuple.Item1, tuple.Item2);
            }
            byte[] assetMessage;
            foreach (IAsset a in _assetsToAdd)
            {
                assetMessage = _encoder.GetBytes(MakeAddAssetString(a));
                WriteToClient(clientStream, assetMessage);
            }
            foreach (IAsset a in _assetsToRemove)
            {
                assetMessage = _encoder.GetBytes(MakeRemoveAssetString(a));
                WriteToClient(clientStream, assetMessage);
            }

            List <Socket> readList        = new List <Socket>();
            bool          heartbeatActive = false;

            byte[] message = new byte[4096];
            int    length  = 0;

            try
            {
                while (mRunning && client.Connected)
                {
                    int bytesRead = 0;

                    try
                    {
                        readList.Clear();
                        readList.Add(client.Client);
                        if (mHeartbeat > 0 && heartbeatActive)
                        {
                            Socket.Select(readList, null, null, mHeartbeat * 2000);
                        }
                        if (readList.Count == 0 && heartbeatActive)
                        {
                            Console.WriteLine("Heartbeat timed out, closing connection\n");
                            break;
                        }

                        //blocks until a client sends a message
                        bytesRead = clientStream.Read(message, length, 4096 - length);
                    }
                    catch (Exception e)
                    {
                        //a socket error has occured
                        Console.WriteLine("Heartbeat read exception: " + e.Message + "\n");
                        break;
                    }

                    if (bytesRead == 0)
                    {
                        //the client has disconnected from the server
                        Console.WriteLine("No bytes were read from heartbeat thread");
                        break;
                    }

                    // See if we have a line
                    int pos = length;
                    length += bytesRead;
                    int eol = 0;
                    for (int i = pos; i < length; i++)
                    {
                        if (message[i] == '\n')
                        {
                            String line = _encoder.GetString(message, eol, i);
                            if (Receive(clientStream, line))
                            {
                                heartbeatActive = true;
                            }
                            eol = i + 1;
                        }
                    }

                    // Remove the lines that have been processed.
                    if (eol > 0)
                    {
                        length = length - eol;
                        // Shift the message array to remove the lines.
                        if (length > 0)
                        {
                            Array.Copy(message, eol, message, 0, length);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error during heartbeat: " + e.Message);
            }

            finally
            {
                try
                {
                    lock (mClients)
                    {
                        mClients.Remove(clientStream);
                    }
                    client.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error during heartbeat cleanup: " + e.Message);
                }
                mActiveClients.Signal();
            }
        }