private void ThreadedReceiver_ServerDataReceived(object sender, AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                ReceiveData data = e.UserState as ReceiveData;
                if (data != null)
                {
                    MessageData messageData = data.clientData;
                    Client      client      = ClientStore.FindClient(data.clientHandle);
                    if (messageData != null && messageData.id > 0)
                    {
                        Console.WriteLine("received Message Type: {0}", messageData.id);
                        if (client != null)
                        {
                            Console.WriteLine("\tFrom Client: {0}", data.clientHandle);

                            // It's a string message, so just print it out for now.
                            Console.WriteLine("[{0}]: {1} ", messageData.name, ((messageData.message is string) ? messageData.message : ((messageData.message as byte[]).Length + " bytes")));
                        }

                        if (MessageFactory != null)
                        {
                            IMessageImpl msgImpl = MessageFactory.MakeMessageImpl(messageData.id, client.ClientHandle);

                            if (msgImpl != default(IMessageImpl))
                            {
                                messageHandler.Handle(client, messageData, msgImpl, this);
                            }
                        }
                    }
                }
            }
        }
        public void SendLoop(object arg)
        {
            Client client = arg as Client;

            if ((client != null) && (client.ClientSocket != null))
            {
                while (!looper.LoopDone)
                {
                    try
                    {
                        var eventData = GetDataAsync.GetMessageDataAsync(client.DataGetter, client.ClientHandle);

                        if (eventData != null)
                        {
                            //if ((eventData.Result != null) && (eventData.Result.id > 0) && (eventData.Result.message != null))
                            if (eventData.Result != null)
                            {
                                byte[] buffer = ClientData <MessageData> .SerializeToByteArray <MessageData>(eventData.Result);

                                var res = TcpLibExtensions.SendBufferAsync(client.ClientSocket, buffer, 0, buffer.Length, SocketFlags.None, client.CancelSource.Token);
                                if (res.IsFaulted || (res.Result == null) || res.Result.Failure)
                                {
                                    // Just close the socket.  Look into trying to reconnect
                                    Console.WriteLine("Send Fault. Closing socket {0} to client.", client.ClientSocket.Handle);
                                    //ClientStore.RemoveClient((long)client.ClientSocket.Handle);
                                }
                                else if (eventData.Result.exitCmd)
                                {
                                    Console.WriteLine("Exit Command Received");
                                    ClientStore.RemoveClient((long)client.ClientSocket.Handle);
                                    client.Stop();
                                }
                                else
                                {
                                    // Data sent.  Clear out buffer
                                    System.Diagnostics.Debug.WriteLine("Client {0} Sent Data.", client.ClientSocket.Handle);
                                    client.ClearData();
                                }
                            }
                            else
                            {
                                Console.WriteLine("Client: {0} -- NULL Message Result", client.ClientHandle);
                            }
                        }
                    }
                    catch (TaskCanceledException tc)
                    {
                        looper.LoopDone = true;
                        System.Diagnostics.Debug.WriteLine("Send Task Cancelled: " + tc.Message);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Send Exception: " + e.Message);
                    }
                }
                Console.WriteLine("Send Loop Exiting...");
            }
        }
        public void ListenLoop(object arg)
        {
            ClientStore clients = arg as ClientStore;

            if (clients != null)
            {
                while (!looper.LoopDone)
                {
                    try
                    {
                        var res = ServerListenAsync(useLocalhost);
                        if (res.IsFaulted || (res.Result == null))
                        {
                            Console.WriteLine("Problem with connection.");
                        }
                        else
                        {
                            Console.WriteLine("Accepted Client Connection on port: {0}", CliServDefaults.DfltPort);
                            Client client = new Client(res.Result, CliServDefaults.BufferSize, dataGetter);
                            try
                            {
                                // Start the service loops
                                client.Start();
                                ClientStore.AddClient(client, client.ClientHandle);
                                OnClientConnect?.Invoke(client);
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("Client Add to List Exception: {0}", e.Message);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
                if (_listenSocket.Connected)
                {
                    _listenSocket.Shutdown(SocketShutdown.Both);
                    _listenSocket.Close();
                }
                Console.WriteLine("Listener Done.");
            }
        }
        /// <summary>
        /// The work done on the receive loop.  It assumes we are receiving MessageData types unless
        /// a MessageData received indicates a file to be received.  Then it switches over to receiving
        /// byte[].
        /// </summary>
        /// <param name="client">The client data is received from</param>
        private void ClientReceive(Client client)
        {
            if ((client == null) || (client.ClientSocket == null))
            {
                return;
            }

            ReceiveData rcvData = new ReceiveData();

            try
            {
                client.ClearData();

                var res = TcpLibExtensions.ReceiveAsync(client.ClientSocket, client.ClientData(), 0, client.DataSize, SocketFlags.None, client.CancelSource.Token);
                if (res.IsFaulted || (res.Result == null) || res.Result.Failure)
                {
                    // Just close the socket.  Look into trying to reconnect
                    Console.WriteLine("Receive Fault. Closing socket {0} to client.", client.ClientSocket.Handle);
                    ClientStore.RemoveClient((long)client.ClientSocket.Handle);
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("Receiving Data From Client: {0}", client.ClientSocket.Handle);
                    try
                    {
                        MessageData value = null;
                        if (receivingFile)
                        {
                            value              = fileMsg;
                            value.message      = client.ClientData();
                            value.length       = res.Result.Value;
                            rcvData.clientData = fileMsg;
                            totalRcv          += res.Result.Value;
                            System.Diagnostics.Debug.WriteLine("Received: Size:[{0}] - [{1}] out of [{2}]", res.Result.Value, totalRcv, fileSize);
                        }
                        else
                        {
                            value = ClientData <MessageData> .DeserializeFromByteArray <MessageData>(client.ClientData());

                            rcvData.clientData = value;
                        }
                        rcvData.clientHandle = (long)client.ClientSocket.Handle;

                        if (value != null)
                        {
                            // This indicates a response from the server to a client of which there could be many
                            if (value.response)
                            {
                                // Client received
                                OnClientDataReceived(new AsyncCompletedEventArgs(null, false, rcvData));
                            }
                            else
                            {
                                if (rcvData.clientData.id == 100)
                                {
                                    if (!receivingFile)
                                    {
                                        receivingFile    = true;
                                        fileSize         = rcvData.clientData.length;
                                        fileMsg.handle   = rcvData.clientData.handle;
                                        fileMsg.id       = rcvData.clientData.id;
                                        fileMsg.name     = rcvData.clientData.name;
                                        fileMsg.response = rcvData.clientData.response;
                                    }
                                    else if (totalRcv >= fileSize)
                                    {
                                        receivingFile = false;
                                        totalRcv      = 0;
                                        Console.WriteLine("Received all file.");
                                    }
                                }
                                // Server received
                                OnServerDataReceived(new AsyncCompletedEventArgs(null, false, rcvData));
                            }
                        }
                        else
                        {
                            // Send null message to client and server so they can detect disconnection
                            OnClientDataReceived(new AsyncCompletedEventArgs(null, false, rcvData));
                            OnServerDataReceived(new AsyncCompletedEventArgs(null, false, rcvData));
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
            }
            catch (TaskCanceledException tc)
            {
                looper.LoopDone = true;
                System.Diagnostics.Debug.WriteLine("receive Task Cancelled: " + tc.Message);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Receive Exception: " + ex.Message);
            }
        }