private void StopAllServices(Exception exception)
 {
     ClipboardNetworkChannel.StopService();
     ClipboardTrasfer.StopService();
     InputNetworkChannel.StopService();
 }
        private void WaitForClients(object arg)
        {
            Settings settings = arg as Settings;

            keepAlive             = new KeepaliveChannel(settings.KeepAlivePort);
            ClientAuthenticated  += Connection_Keeplive_OnClientAuthenticated;
            ClientDisconnected   += StopAllServices;
            ClientDisconnected   += Connection_Keeplive_OnClientDisconnected;
            keepAlive.DeadClient += Connection_Keepalive_OnDeadClient;

            OnStarted();

            while (true)     /*loop among all clients who will connect to me*/

            {
                actualClient = null;
                IPEndPoint clientEndpoint = null;
                byte[]     buffer         = new byte[64];

                try {
                    while (true)     //loop until a client is authenticated

                    {
                        try {
                            actualClient = listener.Accept();
                        } catch (Exception) { /*listening socket closed by Stop()*/
                            goto finish;
                        }

                        clientEndpoint    = (IPEndPoint)actualClient.RemoteEndPoint;
                        settings.ClientIP = clientEndpoint.Address;

                        OnClientConnected(clientEndpoint);

                        int recv = actualClient.Receive(buffer);
                        if (recv == 0)      /*the client shuts down the Socket connection with the Shutdown method*/
                        {
                            throw new SocketException();
                        }

                        bool authenticated = Encoding.Unicode.GetString(buffer).Equals(passwdDigest);

                        if (authenticated)
                        {
                            break;
                        }

                        actualClient.Send(Encoding.Unicode.GetBytes("NO"));
                        actualClient.Shutdown(SocketShutdown.Both);
                        actualClient.Disconnect(true);
                    }
                } catch (SocketException) {
                    actualClient.Shutdown(SocketShutdown.Both);
                    actualClient.Disconnect(true);
                    continue;
                }

                OnClientAuthenticated(); // Client is authenticated. Invoke callbacks and open all channels

                try {
                    IPAddress clientIP = clientEndpoint.Address;

                    ClipboardNetworkChannel.StartService(settings.ClipboardReceivingPort);
                    InputNetworkChannel.StartService(settings.InputReceivingPort);

                    actualClient.Send(Encoding.Unicode.GetBytes("OK"));

                    ClipboardTrasfer.Target = new IPEndPoint(clientIP, settings.ClipboardTransferPort);

                    //wait synchronously for BYE from client before closing correctly the socket
                    actualClient.Receive(buffer);
                    Console.WriteLine("Received " + Encoding.Unicode.GetString(buffer) + " from client");
                } catch (Exception e) {
                    Console.WriteLine("{0}:{1}", e.GetType().Name, e.Message);
                }
                finally {
                    Utility.ShutdownSocket(actualClient);
                    OnClientDisconnected(null);
                }
                //finished serving this client
            }
finish:
            OnStopped();
            Console.WriteLine("Client accepting channel CLOSED!!! BYE");
        }