예제 #1
0
        private void OnTimeEventTestConnection(object source, ElapsedEventArgs e)
        {
            // Send 0 byte buffer, to check if the connection is still alive.
            byte[] zeroByte = new byte[1];

            try
            {
                // Call the call back for the sending.
                _clientSocket.BeginSend(zeroByte, 0, 0, SocketFlags.None, new AsyncCallback(SendConnectionAlivenessVerificationCallback), null);
            }
            catch (Exception ex)
            {
                _serverTimer.Stop();
                _mainWinWMCaller.CancelStringCommand();
                Console.WriteLine(ex.ToString());

                // Close the connection with the server. The disconnect function calls the CloseClient, the Remove server, and the removeProcessesFromApplication.
                System.Windows.Application.Current.Dispatcher.Invoke((Action) delegate
                {
                    // Open the Error Window
                    Views.ErrorWindowView errView         = new Views.ErrorWindowView();
                    ErrorWindowViewModel errWindViewModel = new ErrorWindowViewModel("Connessione interrotta dal server " + this.ServerIpAddress.ToString() + ".");
                    errWindViewModel.ClosingRequest      += errView.Close;
                    errView.DataContext = errWindViewModel;
                    errView.Show();
                });

                _mainWinWMCaller.DisconnectFromServer(_serverIpAddress);
            }
        }
예제 #2
0
        public void SendCommand(List <string> keyCommands, int Handle, int Pid)
        {
            int numKeys = keyCommands.Count();

            // Generate the string that has to be sent.
            string commandToSend = "command " + Handle + " " + Pid + " " + numKeys;

            foreach (string key in keyCommands)
            {
                commandToSend += " " + key;
            }

            // Create the buffer byte that has to be sent.
            byte[] commandByteBuffer = Encoding.Default.GetBytes(commandToSend); // Command to send have variable length

            // Send the dimension of the send byte buffer together with it
            // Ushort is on 2Bytes
            ushort sBBLength = (ushort)commandByteBuffer.Length;

            // Convert the dimension directly into bytes encoding
            byte[] lengthIn2Bytes = BitConverter.GetBytes(sBBLength);

            // Message length is encoded in network byte order (Big Endian), so I need to check if the architecture
            // of the host is Little Endian, in that case reverse the order of the bytes before decoding
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(lengthIn2Bytes);
            }

            byte[] sendByteBuffer = new byte[lengthIn2Bytes.Length + commandByteBuffer.Length];
            Buffer.BlockCopy(lengthIn2Bytes, 0, sendByteBuffer, 0, lengthIn2Bytes.Length);
            Buffer.BlockCopy(commandByteBuffer, 0, sendByteBuffer, lengthIn2Bytes.Length, commandByteBuffer.Length);

            try
            {
                // Call the call back for the sending.
                _clientSocket.BeginSend(sendByteBuffer, 0, sendByteBuffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), null);
            }
            catch (Exception e)
            {
                _mainWinWMCaller.CancelStringCommand();
                Console.WriteLine(e.ToString());
                // Close the connection with the server. The disconnect function calls the CloseClient, the Remove server, and the removeProcessesFromApplication.
                _mainWinWMCaller.DisconnectFromServer(this.ServerIpAddress);

                System.Windows.Application.Current.Dispatcher.Invoke((Action) delegate
                {
                    // Open the Error Window
                    Views.ErrorWindowView errView         = new Views.ErrorWindowView();
                    ErrorWindowViewModel errWindViewModel = new ErrorWindowViewModel("Invio non riuscito, server disconnesso.");
                    errWindViewModel.ClosingRequest      += errView.Close;
                    errView.DataContext = errWindViewModel;
                    errView.Show();
                });
            }
        }
예제 #3
0
        /*******************
        * PRIVATE METHODS *
        *******************/

        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                _clientSocket.EndConnect(ar);

                if (_clientSocket.Connected) // There is connection
                {
                    // Notify the GUI the connetions has been performerd
                    _mainWinWMCaller.NotificationMessage = "Client connected to server " + _serverIpAddress;

                    // Start the timer to keep track of the connection time.
                    _connectionTimer.Start();

                    // Start the timer to check the connection aliveness.
                    _serverTimer.Start();

                    // Add the server to the data structures.
                    System.Windows.Application.Current.Dispatcher.Invoke((Action) delegate {
                        _mainWinWMCaller.AddServer(this, _serverIpAddress);
                    });

                    // Set this newly created Server as the Currently selected one.
                    _mainWinWMCaller.CurrentSelectedServer = this;

                    // Update the comboBox.
                    _mainWinWMCaller.CurrentServerChanged(_serverIpAddress);

                    // Start receiving data from the server.
                    Receive(2);
                }
            }
            catch (Exception e)
            {
                // _connectionResult.AsyncWaitHandle.WaitOne(5000, true);

                System.Windows.Application.Current.Dispatcher.Invoke((Action) delegate
                {
                    // Open the Error Window
                    Views.ErrorWindowView errView         = new Views.ErrorWindowView();
                    ErrorWindowViewModel errWindViewModel = new ErrorWindowViewModel("Connessione con " + this.ServerIpAddress.ToString() + " non riuscita.");
                    errWindViewModel.ClosingRequest      += errView.Close;
                    errView.DataContext = errWindViewModel;
                    errView.Show();
                });

                // Remove the server Ip Address from the structure that contains it as a key
                if (_mainWinWMCaller.ListOfConnectionThreads.ContainsKey(this.ServerIpAddress))
                {
                    _mainWinWMCaller.ListOfConnectionThreads.Remove(this.ServerIpAddress);
                }

                Console.WriteLine(e.ToString());
                CloseClient();
            }
        }
예제 #4
0
        private void SendConnectionAlivenessVerificationCallback(IAsyncResult ar)
        {
            SocketError sockErr = new SocketError();

            try
            {
                // End the sending.
                int bytesSent = _clientSocket.EndSend(ar, out sockErr);
                if (!sockErr.Equals(SocketError.Success) && !sockErr.Equals(SocketError.WouldBlock))
                {
                    _mainWinWMCaller.CancelStringCommand();
                    // Close the connection with the server. The disconnect function calls the CloseClient, the Remove server, and the removeProcessesFromApplication.
                    _mainWinWMCaller.DisconnectFromServer(this.ServerIpAddress);

                    System.Windows.Application.Current.Dispatcher.Invoke((Action) delegate
                    {
                        // Open the Error Window
                        Views.ErrorWindowView errView         = new Views.ErrorWindowView();
                        ErrorWindowViewModel errWindViewModel = new ErrorWindowViewModel("Server " + this.ServerIpAddress.ToString() + " disconnesso.");
                        errWindViewModel.ClosingRequest      += errView.Close;
                        errView.DataContext = errWindViewModel;
                        errView.Show();
                    });
                }
            }
            catch (Exception e)
            {
                // Check if the socket error is not WouldBlock (that is not a proper error):
                // in this case return without taking action
                if (sockErr.Equals(SocketError.WouldBlock))
                {
                    Console.WriteLine(e.ToString());
                }
                else
                {
                    _mainWinWMCaller.CancelStringCommand();
                    Console.WriteLine(e.ToString());
                    // Close the connection with the server. The disconnect function calls the CloseClient, the Remove server, and the removeProcessesFromApplication.
                    _mainWinWMCaller.DisconnectFromServer(this.ServerIpAddress);

                    System.Windows.Application.Current.Dispatcher.Invoke((Action) delegate
                    {
                        // Open the Error Window
                        Views.ErrorWindowView errView         = new Views.ErrorWindowView();
                        ErrorWindowViewModel errWindViewModel = new ErrorWindowViewModel("Server " + this.ServerIpAddress.ToString() + " disconnesso.");
                        errWindViewModel.ClosingRequest      += errView.Close;
                        errView.DataContext = errWindViewModel;
                        errView.Show();
                    });
                }
            }
        }
예제 #5
0
        /******************
        * PUBLIC METHODS *
        ******************/

        public void StartClient()
        {
            // Connect to a remote device.
            try
            {
                // Establish the remote endpoint for the socket.

                IPAddress  ipAddress = _serverIpAddress;
                IPEndPoint remoteEP  = new IPEndPoint(ipAddress, _port);

                // Create a TCP/IP socket.
                _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                // Connect to the remote endpoint.
                _connectionResult = _clientSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), null);
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception : {0}", e.ToString());

                System.Windows.Application.Current.Dispatcher.Invoke((Action) delegate
                {
                    // Open the Error Window
                    Views.ErrorWindowView errView         = new Views.ErrorWindowView();
                    string errormessage                   = "La connessione con il server è fallita";
                    ErrorWindowViewModel errWindViewModel = new ErrorWindowViewModel(errormessage);
                    errWindViewModel.ClosingRequest      += errView.Close;
                    errView.DataContext                   = errWindViewModel;
                    errView.Show();
                });

                // Remove the server Ip Address from the structure that contains it as a key
                if (_mainWinWMCaller.ListOfConnectionThreads.ContainsKey(this.ServerIpAddress))
                {
                    _mainWinWMCaller.ListOfConnectionThreads.Remove(this.ServerIpAddress);
                }

                // Close the Socket
                CloseClient();
            }
        }
 // Intercept the disconnet_button_click, to stop if in the ApplicationView.
 private void DisconnectFromServerButton_Click(object sender, RoutedEventArgs e)
 {
     if (_mainWindowViewModel != null)
     {
         if (_mainWindowViewModel.IsDisconnectButtonEnabled)
         {
             // Check that there is a currentSelectedServer!
             if (_mainWindowViewModel.CurrentSelectedServer != null)
             {
                 _mainWindowViewModel.CurrentSelectedServer.HasToStopTimer = true;
                 _mainWindowViewModel.DisconnectFromServer(_mainWindowViewModel.CurrentSelectedServer.ServerIpAddress);
             }
         }
         else
         {
             // Open the Error Window
             Views.ErrorWindowView errView          = new Views.ErrorWindowView();
             ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Per disconnettere un server, andare sulla vista Server.");
             errWindViewModel.ClosingRequest += errView.Close;
             errView.DataContext              = errWindViewModel;
             errView.Show();
         }
     }
 }
예제 #7
0
        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                // Read data from the remote device.
                int bytesRead = _clientSocket.EndReceive(ar);

                // There is something to read
                if (bytesRead > 0)
                {
                    // Update the counter of reeived bytes.
                    _receiveBufferCounter += bytesRead;

                    if (_receiveBufferCounter > 0 && _receiveBufferCounter < _bytesToRead)
                    {
                        // I still need to receive data for the current message.

                        // Save what I received up to now, and listen again the socket.
                        Array.Copy(_receiveByteBuffer, 0, _storedByteBuffer, _receiveBufferCounter - bytesRead, bytesRead);

                        // Call the Receive again, to reed more bytes.
                        Receive(_bytesToRead - _receiveBufferCounter);
                    }

                    else if (_receiveBufferCounter == _bytesToRead)
                    {
                        // The counter is equal to _bytesToRead, the read is now complete.

                        // Still need to copy in the buffer what I have just received.
                        Array.Copy(_receiveByteBuffer, 0, _storedByteBuffer, _receiveBufferCounter - bytesRead, bytesRead);

                        // I read the first 2 bytes of a message containing its length
                        if (_receiveBufferCounter == 2)
                        {
                            // Message length is encoded in network byte order (Big Endian), so I need to check if the architecture
                            // of the host is Little Endian, in that case reverse the order of the bytes before decoding
                            if (BitConverter.IsLittleEndian)
                            {
                                Array.Reverse(_storedByteBuffer);
                            }

                            ushort messageLength = BitConverter.ToUInt16(_storedByteBuffer, 0);

                            nextRead = true;
                            Receive(messageLength);
                        }

                        else
                        {
                            // Then I can start processing the data.

                            // Create a string and get the received content of the buffer.
                            string receivedString = Encoding.Default.GetString(_storedByteBuffer);

                            string[] lines = Regex.Split(receivedString, "\n");

                            if (lines[0].Equals("newwindow")) // newwindows\n<path_exe>\n<nome_finestra>\n<handle>\n<pid>\n<dim_icona>\n<byteicon>
                            {
                                // I have a new window to listen about, and then add the to the ServerModel
                                string exePath = lines[1];
                                // Create the path and extract the file (program) name.
                                string windowName    = lines[2];
                                int    processHandle = Int32.Parse(lines[3]);
                                int    processID     = Int32.Parse(lines[4]);
                                // Set anyway the image as null.
                                BitmapImage icon = null;

                                if (lines.Length > 6)
                                {
                                    // Means that there also information about the image, otherwise there is not
                                    int iconDimension = Int32.Parse(lines[5]);

                                    // If the iconDimension is < 0, that means that there were some errors: don't even read the rest of the message.
                                    if (iconDimension > 0)
                                    {
                                        // Means that the Icon has been properly sent
                                        icon = new BitmapImage();

                                        byte[] imageByte = new byte[iconDimension];


                                        // Compute the index of the start of the byte of the icon, so the already processed bytes.
                                        int iconOffset = 0;
                                        for (int i = 0; i < 6; i++)
                                        {
                                            iconOffset += lines[i].Length + 1;
                                        }

                                        // Take the image byte from the receivedByte, not from the receivedString, because it could have some \n characters.
                                        Array.Copy(_storedByteBuffer.Skip(iconOffset).ToArray(), imageByte, iconDimension);

                                        // Save the byte as a BitMapImage
                                        using (var stream = new MemoryStream(imageByte))
                                        {
                                            stream.Position = 0;
                                            icon.BeginInit();
                                            icon.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
                                            icon.CacheOption   = BitmapCacheOption.OnLoad;
                                            icon.StreamSource  = stream;
                                            icon.EndInit();
                                            icon.Freeze();
                                        }
                                    }
                                }

                                // Create the processModel with its constructor
                                // Icon can be null
                                ProcessModel newProcessM = new ProcessModel(windowName, exePath, processHandle, processID, icon);

                                // Set the notification message for the GUI.
                                _mainWinWMCaller.NotificationMessage = "Server: " + _serverIpAddress.ToString() + ".\nNew window " + newProcessM.ExePath + " has been created.";

                                // The process must be added in the ListofProcesses of the ServerModel
                                System.Windows.Application.Current.Dispatcher.Invoke((Action) delegate
                                {
                                    _processList.Add(newProcessM);
                                });

                                // Update the process list the of the mainWindowModel.
                                _mainWinWMCaller.RaisePropertyChanged("TheProcessesList");

                                // Add this process to the applications of the same type
                                AddProcessToApplication(newProcessM);
                            }

                            if (lines[0].Equals("closed")) // closed\n<handle>\n<pid>
                            {
                                // I have received a notification from the server: one window have been closed.

                                // Extract Handle and PID
                                string[] handleAndPID = Regex.Split(lines[1], " ");
                                int      handle       = Int32.Parse(handleAndPID[0]);
                                int      pid          = Int32.Parse(handleAndPID[1]);

                                // Remove the Windows from the process lists. Find the process.
                                foreach (ProcessModel proc in _processList)
                                {
                                    // Check if the window has the focus (different from null and they have the same handle)
                                    if (_focusedProcess != null && _focusedProcess.ProcessWindowHandle.Equals(proc.ProcessWindowHandle))
                                    {
                                        // Check if the window has the focus (different from null and they have the same handle)
                                        if (_focusedProcess != null && _focusedProcess.ProcessWindowHandle.Equals(proc.ProcessWindowHandle))
                                        {
                                            _focusedProcess.PauseWatch();
                                            _focusedProcess = null;
                                        }

                                        System.Windows.Application.Current.Dispatcher.Invoke((Action) delegate
                                        {
                                            // Remove the process from the process list.
                                            _processList.Remove(proc);

                                            // Remove the process from the list of applications.
                                            RemoveProcessFromApplications(proc);
                                        });

                                        // Set the notification message for the GUI.
                                        _mainWinWMCaller.NotificationMessage = "Server: " + _serverIpAddress.ToString() + ".\nProcess " + proc.ExePath + " has been closed.";

                                        // Exit the for loop.
                                        break;
                                    }
                                }
                            }

                            if (lines[0].Equals("focus"))
                            {
                                // I have received a notification, the window with focus has changed.

                                if (lines[1].Equals("nullwindow"))
                                {
                                    // There is no focused window. Stop the focus: interrupt a timer.
                                    // But only if the focused process already exists
                                    if (_focusedProcess != null)
                                    {
                                        _focusedProcess.PauseWatch();
                                        _focusedProcess.ProcessStatus = "";
                                        _focusedProcess = null;
                                    }
                                    _mainWinWMCaller.NotificationMessage = "Server: " + _serverIpAddress.ToString() + ".\nFocus set on: null.";
                                }
                                if (lines[1].Equals("windowsoperatingsystem"))
                                {
                                    // The focus is hold by the operating system. Stop the focus: interrupt a timer
                                    // But only if the focused process already exists
                                    if (_focusedProcess != null)
                                    {
                                        _focusedProcess.PauseWatch();
                                        _focusedProcess.ProcessStatus = "";
                                        _focusedProcess = null;
                                    }
                                    _mainWinWMCaller.NotificationMessage = "Server: " + _serverIpAddress.ToString() + ".\nFocus set on: Operating System.";
                                }
                                if (lines[1].All(char.IsDigit)) // Check that the string is a number.
                                {
                                    // A window holds the focus.
                                    int handle = Int32.Parse(lines[1]);
                                    int pid    = Int32.Parse(lines[2]);

                                    // Change the focus: interrupt a timer (if there was one running) and start another.
                                    // But only if the focused process already exists
                                    if (_focusedProcess != null)
                                    {
                                        _focusedProcess.PauseWatch();
                                        _focusedProcess.ProcessStatus = "";
                                    }

                                    // Find the focused process.
                                    foreach (ProcessModel proc in _processList)
                                    {
                                        if (proc.ProcessWindowHandle == handle)
                                        {
                                            // Set this process as the focused one.
                                            _focusedProcess = proc;
                                            // Exit the for loop.
                                            break;
                                        }
                                    }
                                    _focusedProcess.RestartWatch();
                                    _focusedProcess.ProcessStatus        = "On Focus";
                                    _mainWinWMCaller.NotificationMessage = "Server: " + _serverIpAddress.ToString() + ".\nFocus set on: " + _focusedProcess.ExePath + ".";
                                }
                            }

                            // Set the flag to read next block and go back to listen on the socket.
                            nextRead = true;
                            Receive(2);
                        }
                    }
                }

                else if (bytesRead == 0)
                {
                    // In am in the case of a graceful disconnection, shutdown of the server from the serverside.

                    // Stop the Check Connection Timer
                    ServerTimer.Stop();

                    // Close the connection with the server. The disconnect function calls the CloseClient, the Remove server, and the removeProcessesFromApplication.
                    _mainWinWMCaller.DisconnectFromServer(this.ServerIpAddress);

                    // Close the connection with the server. The disconnect function calls the CloseClient, the Remove server, and the removeProcessesFromApplication.
                    System.Windows.Application.Current.Dispatcher.Invoke((Action) delegate
                    {
                        // Open the Error Window
                        Views.ErrorWindowView errView         = new Views.ErrorWindowView();
                        ErrorWindowViewModel errWindViewModel = new ErrorWindowViewModel("Connessione interrotta dal server " + this.ServerIpAddress.ToString() + ".");
                        errWindViewModel.ClosingRequest      += errView.Close;
                        errView.DataContext = errWindViewModel;
                        errView.Show();
                    });
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
        public void SendCommand()
        {
            // Divide the cases: the one with the ServerView and the one with the ApplicationView

            if (_shouldShowServer)
            {
                // The selected view is the one of the servers.

                // If there is at lest a key in the command
                if (_keyStrings.Count() != 0)
                {
                    // If there is a CurrentSelectedServer
                    if (CurrentSelectedServer != null)
                    {
                        // If there is a process selected.
                        if (CurrentSelectedProcess != null)
                        {
                            CurrentSelectedServer.SendCommand(_keyStrings, _currentSelectedProcess.ProcessWindowHandle, _currentSelectedProcess.ProcessId);
                        }
                        else // The CurrentSelectedProcess is null, show the Error Window.
                        {
                            // Open the Error Window
                            Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                            ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Nessuna finestra selezionata.");
                            errWindViewModel.ClosingRequest += errView.Close;
                            errView.DataContext              = errWindViewModel;
                            errView.Show();
                        }
                    }
                    else // The CurrentSelectedServer is null, show the Error Window.
                    {
                        // Open the Error Window
                        Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                        ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Non è selezionato nessun server.");
                        errWindViewModel.ClosingRequest += errView.Close;
                        errView.DataContext              = errWindViewModel;
                        errView.Show();
                    }
                }
                else // There is no command to send.
                {
                    // Open the Error Window
                    Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                    ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Nessun comando inserito.");
                    errWindViewModel.ClosingRequest += errView.Close;
                    errView.DataContext              = errWindViewModel;
                    errView.Show();
                }

                // Clean the textBox in the GUI and clean the list of keys.
                CancelStringCommand();
            }
            else if (_shouldShowApplication)
            {
                // The selected view is the one of the applications.

                // If there is at lest a key in the command
                if (_keyStrings.Count() != 0)
                {
                    // If there is a selected application.
                    if (CurrentSelectedApplication != null)
                    {
                        // If the are selected severs.
                        if (SelectedServersForApplication != null)
                        {
                            // If there is at least a server selected for the selected application.
                            if (SelectedServersForApplication.Count() > 0)
                            {
                                // For each server selected, send the signal to all the applications it runs, that have the same application name of the one selected.
                                foreach (ServerModel server in SelectedServersForApplication)
                                {
                                    foreach (ProcessModel process in server.TheProcesses)
                                    {
                                        // I have to check if the exeName of the process is equal to the selected application.
                                        string processExeName = Path.GetFileName(process.ExePath); // returns File.exe

                                        if (processExeName.Equals(_currentSelectedApplication.ApplicationName))
                                        {
                                            // I have to send the command, since they are the same application
                                            server.SendCommand(_keyStrings, process.ProcessWindowHandle, process.ProcessId);
                                        }
                                    }
                                }
                                CancelStringCommand();
                            }
                            else // There is no selected server.
                            {
                                // Open the Error Window
                                Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                                ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Non è selezionato nessun server.");
                                errWindViewModel.ClosingRequest += errView.Close;
                                errView.DataContext              = errWindViewModel;
                                errView.Show();
                            }
                        }
                        else // There is no selected server.
                        {
                            // Open the Error Window
                            Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                            ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Non è selezionato nessun server.");
                            errWindViewModel.ClosingRequest += errView.Close;
                            errView.DataContext              = errWindViewModel;
                            errView.Show();
                        }
                    }
                    else // There is no selected application.
                    {
                        // Open the Error Window
                        Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                        ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Non è selezionata nessuna applicazione.");
                        errWindViewModel.ClosingRequest += errView.Close;
                        errView.DataContext              = errWindViewModel;
                        errView.Show();
                    }
                }
                else // There is no command to send.
                {
                    // Open the Error Window
                    Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                    ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Nessun comando inserito.");
                    errWindViewModel.ClosingRequest += errView.Close;
                    errView.DataContext              = errWindViewModel;
                    errView.Show();
                }
            }
        }
        // Disconnect the client from the currently selected Server
        public void DisconnectFromServer(IPAddress ipServerToDisconnect)
        {
            if (ipServerToDisconnect != null)
            {
                ServerModel serverToDisconnect = null;

                // From the Ip look-up the server.
                foreach (ServerModel server in ServerConnections)
                {
                    if (server.ServerIpAddress.Equals(ipServerToDisconnect))
                    {
                        serverToDisconnect = server;
                        // Stop the serverTimer if the disconnect is called from the GUI
                        if (serverToDisconnect.HasToStopTimer)
                        {
                            serverToDisconnect.ServerTimer.Stop();
                        }
                        break;
                    }
                }

                if (serverToDisconnect != null)
                {
                    // I found the server I want to disconnect

                    if (serverToDisconnect.Equals(CurrentSelectedServer))
                    {
                        // I want to disconnect the currentSelectedServer
                        serverToDisconnect.CloseClient();
                        // The function calls already the RemoveServer function

                        // Remove the server information form the GUI
                        NotificationMessage = "Server " + ipServerToDisconnect.ToString() + " disconnesso.";

                        // If there are other servers, select the first of them
                        if (ServerConnections.Count() > 0)
                        {
                            // Select the first server.
                            CurrentSelectedServer    = ServerConnections.First();
                            CurrentSelectedIpAddress = CurrentSelectedServer.ServerIpAddress;
                            CurrentSelectedProcess   = null;
                            TheProcessesList         = CurrentSelectedServer.TheProcesses;
                            // Update the GUI
                            RaisePropertyChanged("TheProcessesList");
                            RaisePropertyChanged("CurrentSelectedIpAddress");
                            RaisePropertyChanged("CurrentSelectedServer");
                            RaisePropertyChanged("CurrentSelectedProcess");
                            RaisePropertyChanged("IpConnections");
                        }
                        else // There are no more connected servers.
                        {
                            CurrentSelectedServer    = null;
                            CurrentSelectedProcess   = null;
                            CurrentSelectedIpAddress = null;
                            TheProcessesList         = null;
                            // Update the GUI
                            RaisePropertyChanged("TheProcessesList");
                            RaisePropertyChanged("CurrentSelectedIpAddress");
                            RaisePropertyChanged("CurrentSelectedServer");
                            RaisePropertyChanged("CurrentSelectedProcess");
                            RaisePropertyChanged("IpConnections");
                        }
                    }
                    else
                    {
                        // The server I want to disconnect is just one among the others.
                        // Close takes care of calling the removeProcessfromApplications and the remove server.
                        serverToDisconnect.CloseClient();
                        // Update the GUI
                        RaisePropertyChanged("TheProcessesList");
                        RaisePropertyChanged("CurrentSelectedIpAddress");
                        RaisePropertyChanged("CurrentSelectedServer");
                        RaisePropertyChanged("CurrentSelectedProcess");
                        RaisePropertyChanged("IpConnections");
                    }
                }
                else // I haven't found the server I am looking for
                {
                    System.Windows.Application.Current.Dispatcher.Invoke((Action) delegate
                    {
                        // Open the Error Window
                        Views.ErrorWindowView errView         = new Views.ErrorWindowView();
                        ErrorWindowViewModel errWindViewModel = new ErrorWindowViewModel("Non è stato trovato il server da disconnettere.");
                        errWindViewModel.ClosingRequest      += errView.Close;
                        errView.DataContext = errWindViewModel;
                        errView.Show();
                    });
                }
            }
            else // No server is selected
            {
                // Open the Error Window
                Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Non è selezionato nessun server.");
                errWindViewModel.ClosingRequest += errView.Close;
                errView.DataContext              = errWindViewModel;
                errView.Show();
            }
        }
        /******************
        * PUBLIC METHODS *
        ******************/

        // Connect the Client with the Server.
        public void ConnectToServer()
        {
            // Check that the Ip Address is in the right and expected form.
            if (IpAddress != null)
            {
                if (Regex.IsMatch(IpAddress, @"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$"))
                {
                    // Set a flag to check that the address in within the boundaries.
                    bool wrongIpAddress = false;
                    // Split the address in the numbers.
                    string[] ipNumbers = IpAddress.Split('.');
                    foreach (string num in ipNumbers)
                    {
                        if (Int32.Parse(num) > 255)
                        {
                            // If a number is too big (can not be smaller than zero, checked in the regex) change the flag value.
                            wrongIpAddress = true;
                        }
                    }

                    // If the address is correct
                    if (!wrongIpAddress)
                    {
                        IPAddress serverIpAddress = IPAddress.Parse(IpAddress);

                        if (!ListOfConnectionThreads.ContainsKey(serverIpAddress))
                        {
                            // Clean the Input string
                            IpAddress = "";

                            // Create the thread passing a parameter, the serverIpAddress I want to connect with.
                            Thread myNewThread = new Thread(() => ServerThreadRoutine(serverIpAddress));

                            // Add the thread to the data structure.
                            ListOfConnectionThreads.Add(serverIpAddress, myNewThread);

                            // Start the thread.
                            myNewThread.Start();
                        }
                        else // The address is already inserted in the IpConnections
                        {
                            // Open the Error Window
                            Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                            ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("La connessione con questo server già è presente.");
                            errWindViewModel.ClosingRequest += errView.Close;
                            errView.DataContext              = errWindViewModel;
                            errView.Show();
                        }
                    }
                    else // The address is not in the proper form, show the ErrorWindow.
                    {
                        // Open the Error Window
                        Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                        ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Formato indirizzo Ip sbagliato.");
                        errWindViewModel.ClosingRequest += errView.Close;
                        errView.DataContext              = errWindViewModel;
                        errView.Show();
                    }
                }
                else // The address is not in the proper form, show the ErrorWindow.
                {
                    // Open the Error Window
                    Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                    ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Formato indirizzo Ip sbagliato.");
                    errWindViewModel.ClosingRequest += errView.Close;
                    errView.DataContext              = errWindViewModel;
                    errView.Show();
                }
            }
            else // The IpAddress is null, show the Error Window.
            {
                // Open the Error Window
                Views.ErrorWindowView errView          = new Views.ErrorWindowView();
                ErrorWindowViewModel  errWindViewModel = new ErrorWindowViewModel("Indirizzo Ip assente.");
                errWindViewModel.ClosingRequest += errView.Close;
                errView.DataContext              = errWindViewModel;
                errView.Show();
            }
        }