Exemplo n.º 1
0
        // Protected methods:
        protected void Communicate(SocketCommunication mode, object sender = null)
        {
            byte message;

            switch (mode)
            {
            case SocketCommunication.SendMove:
                message = 4;
                if ((Directions?)sender != null)
                {
                    message = (byte)(Directions?)sender;
                }
                CLIENT.Send(new byte[] { message });
                break;

            case SocketCommunication.ReceiveMove:
                CLIENT.Receive(Buffer_movement);
                ProcessInfo(Buffer_movement[0]);
                break;

            case SocketCommunication.SendShoot:
                message = (byte)((bool)sender ? 1 : 0);
                CLIENT.Send(new byte[] { message });
                break;

            case SocketCommunication.ReceiveShoot:
                CLIENT.Receive(Buffer_shooting);
                ProcessInfo(Buffer_shooting[0], shootMode: true);
                break;

            default:
                throw new Exception("Not implemented SocketCommunication enum.");
            }
        }
        /*
         * Event handler for clicks on the "Disconnect" in the contextMenuStrip
         */
        private void disconnectServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TcpClient toRemove = this.remoteHosts[ServerList.SelectedItem.ToString()]; /* The client to remove is the client current selected */


            if (this.targetServer != null && this.targetServer.Equals(toRemove)) /*If we are removing the actual target server we have to assign null to tcpcl in order to avoid*/
            {
                this.targetServer = null;                                        /*transfers toward a disconnected server.*/
            }
            try
            {
                if (toRemove != null && toRemove.Connected) /* Standards checks */
                {
                    message msg = new message();
                    msg.messType = messageType.DISCONNECT; /* Message Type: Disconnect! */

                    byte[] buffer = SocketCommunication.rawSerialize(msg);
                    SocketCommunication.sendBufferToSocket(buffer, toRemove);
                }

                toRemove.Close();                                                 /*Here we are closing the socket connected with the server to remove from ServerList*/
                this.remoteHosts.Remove(ServerList.SelectedItem.ToString());      /* We have to remove the server from tme remoteHosts dictionary */
                this.ServerList.Items.Remove(ServerList.SelectedItem.ToString()); /* And from the extern list! */
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        /*
         * Listener for mouse movements in the "MouseArea box". Here we capture each mouse movement and we send this event (mouse coordinates update)
         * toward the server actually connected.
         */
        private void MouseArea_MouseMove(object sender, MouseEventArgs e)
        {
            message msg = new message(); /* Message struct to send to the Server */

            try
            {
                if (targetServer != null && targetServer.Connected) /* If no server is actually connected, we have to sent nothing */
                {
                    msg.act.eventype = EVENTYPE.MOUSE_MOVEMENT;     /* Type of event: mouse movement */

                    /*
                     * Mouse coordinates in the MouseArea box, that maps the server screen. The mouse coordinates ti send with SendInput are mapped
                     * in the value range 0 - 65536.
                     */
                    msg.act.x = (Cursor.Position.X - MouseArea.Location.X) * 65536 / MouseArea.Width;
                    msg.act.y = (Cursor.Position.Y - MouseArea.Location.Y) * 65536 / MouseArea.Height;

                    msg.messType = messageType.ACTION; /* Type of message: mouse or keyboard action, that must be sent via SendInput by the Server. */

                    /*
                     * Here we send all data to the server via Socket.
                     */
                    byte[] buffer = SocketCommunication.rawSerialize(msg);        /*Raw Serialize: Struct Serialization*/
                    SocketCommunication.sendBufferToSocket(buffer, targetServer); /*Buffer sending*/
                }
            }
            catch (Exception ex) /*If some exception occurs, we will show a message with the Error Description*/
            {
                MessageBox.Show(ex.Message);
            }
        }
        /*
         * Listener for mouse wheel in the "MouseArea box". Here we capture each mouse wheel in MouseArea box and we will send this event (mouse wheel)
         * toward the server actually connected.
         */
        private void MouseArea_MouseWheel(object sender, MouseEventArgs e)
        {
            message msg = new message();

            try
            {
                if (targetServer != null && targetServer.Connected) /* If no server is actually connected, we have to sent nothing */
                {
                    msg.act.eventype      = EVENTYPE.MOUSE_WHEEL;   /* Event type: Mouse Wheel! */
                    msg.act.wheelMovement = e.Delta;                /* e.Delta contains the number of wheel rotations. */

                    msg.messType = messageType.ACTION;              /* Type of message: mouse or keyboard action, that must be sent via SendInput by the Server. */

                    /*
                     * Here we send all data to the server via Socket.
                     */
                    byte[] buffer = SocketCommunication.rawSerialize(msg);        /*Raw Serialize: Struct Serialization*/
                    SocketCommunication.sendBufferToSocket(buffer, targetServer); /*Buffer sending*/
                }
            }
            catch (Exception ex) /*If some exception occurs, we will show a message with the Error Description*/
            {
                MessageBox.Show(ex.Message);
            }
        }
        /*
         * Button to close the application
         */
        private void X_Click(object sender, EventArgs e)
        {
            /*
             * First thing: sending a DISCONNECT message to all connected servers.
             */
            if (remoteHosts != null)
            {
                foreach (TcpClient tc in this.remoteHosts.Values)
                {
                    if (tc.Connected) /*If tc is still an active server*/
                    {
                        message msg = new message();
                        msg.messType = messageType.DISCONNECT;

                        byte[] buffer = SocketCommunication.rawSerialize(msg);
                        SocketCommunication.sendBufferToSocket(buffer, tc);

                        tc.Close(); /* Socket close! */
                    }
                }
            }

            /*
             * Here we close the application.
             */
            Application.Exit();
        }
Exemplo n.º 6
0
        static void Main()
        {
            Console.WriteLine("Entry point");

            SocketCommunication socket = new SocketCommunication("server");

            ChatServerSide server = new ChatServerSide(socket);

            server.Start();
        }
Exemplo n.º 7
0
        public void Communicate()
        {
            SocketCommunication socketCommunication = new SocketCommunication();

            if (socketCommunication.IsConnected())
            {
                System.Console.WriteLine("Socket communication established");
                AdminController ctrl = new AdminController(socketCommunication);
                ctrl.HandleCommands();
            }
            socketCommunication.ReleaseSocket();
        }
Exemplo n.º 8
0
        static void Main()
        {
            Console.WriteLine("Entry point");

            SocketCommunication socket = new SocketCommunication("client");

            DataReader dataReader = new DataReader();

            ChatClientSide client = new ChatClientSide(socket, dataReader);

            client.Start();
        }
        /*
         * Performing a double click in a server in the Server List, we will select this server as Target, and we will update
         * the server clipboard with the clipboard data actually present in the client.
         */
        private void ServerList_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            message msg = new message();

            if (ServerList.SelectedItem == null)
            {
                return;                                                     /* If we perform a double click where there is no item, return here. */
            }
            TcpClient cl = remoteHosts[ServerList.SelectedItem.ToString()]; /*The new Server is the current selected server.*/

            byte[] buffer;

            try
            {
                if (this.targetServer == null || !this.targetServer.Equals(cl))   /* If we are selecting the same target server, we do not have to send TARGET_CHANGED and TARGET messages */
                {
                    if (this.targetServer != null && this.targetServer.Connected) /*Here we are informing the old server that it is not longer the client target*/
                    {
                        msg.messType = messageType.TARGET_CHANGED;                /* Type of message: Target_Changed! */

                        buffer = SocketCommunication.rawSerialize(msg);
                        SocketCommunication.sendBufferToSocket(buffer, targetServer);
                    }

                    /*
                     * Here we change the Server and we will inform the new server that it is the new client target!
                     */

                    this.targetServer = cl;            /*The new tcpcl is the selected Server cl*/

                    msg.messType = messageType.TARGET; /* Type of message: Target! */

                    buffer = SocketCommunication.rawSerialize(msg);
                    SocketCommunication.sendBufferToSocket(buffer, targetServer);
                }

                /*
                 * Performing this operation we will unblock the sender thread, that Will analyze the clipboard and will send clipboard
                 * data toward the new Server. Note that if we perform a double click on the current target server, this operation will be anyway performed.
                 */
                send.Set();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        /*
         * The system calls this function every time a new keyboard input event is about to be posted into this thread input queue.
         * In fact, this function is the keyboard listener, that send keyboards Events toward the current targete server.
         */
        public int LowLevelKeyboardProc(int code, int wParam, ref keyboardHookStruct lParam)
        {
            message msg = new message();

            byte[] buffer;

            try
            {
                /* A code the hook procedure uses to determine how to process the message. If nCode is less than zero,
                 * the hook procedure must pass the message to the CallNextHookEx function without further processing and
                 * should return the value returned by CallNextHookEx. Obviously, to send the message tcpcl has to be connected and not null :)
                 */
                if (code >= 0 && targetServer != null && targetServer.Connected)
                {
                    if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))     /* keydown case. We send toward the server both normal keys and system keys. */
                    {
                        msg.act.eventype = EVENTYPE.KEY_DOWN;
                    }
                    else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP))    /* Keyup case. */
                    {
                        msg.act.eventype = EVENTYPE.KEY_UP;
                    }

                    msg.act.keypress = lParam.vkCode;     /* vkCode of the kay that has been pressed. */
                    msg.messType     = messageType.ACTION;

                    buffer = SocketCommunication.rawSerialize(msg);
                    SocketCommunication.sendBufferToSocket(buffer, targetServer);

                    return(1);
                }
                else
                {
                    /*
                     * We do not perform any operation and we call the next function in the HookProcChain.
                     */
                    return(CallNextHookEx(hhook, code, wParam, ref lParam));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return(CallNextHookEx(hhook, code, wParam, ref lParam)); /*If an exception*/
            }
        }
Exemplo n.º 11
0
        private void button1_Click(object sender, EventArgs e)
        {
            TcpClient tcpcl;    /*tcp Client that will connect to the new server*/
            message   msg;

            try
            {
                string ip_addr  = textBox1.Text.ToString();                  /* Get the IP address inserted by the user */
                string password = textBox3.Text.ToString();                  /* Get the password inserted by the user */

                UInt16    port = Convert.ToUInt16(textBox2.Text.ToString()); /* Convert the port string to UInt16 type */
                IPAddress ip   = IPAddress.Parse(ip_addr);                   /* Convert the string IP to IPAddress type */

                tcpcl = new TcpClient();
                tcpcl.Connect(ip, port);                                   /* Here we try to connect with the new Server. */

                byte[] data = Encoding.Unicode.GetBytes(password);         /* Here we are converting the password to a byte array */
                SocketCommunication.sendBufferToSocket(data, tcpcl);       /* Then we send the byte array with the password to the server. */

                data = SocketCommunication.receiveBufferFromSocket(tcpcl); /* Here we're receiving the server reply, that shows if the password is correct. */

                msg = SocketCommunication.rawDeserialize <message>(data);  /* Here we deserialize the received buffer. */

                if (msg.messType == messageType.CONNECTION_REFUSED)        /* If the message contains "Connection Refused", the password is probably wrong. */
                {
                    throw new Exception("Wrong Password");
                }

                if (msg.messType != messageType.CONNECTION_ACCEPTED) /* The server has to reply with a "CONNECTION_ACCEPTED message" */
                {
                    throw new Exception("Error!");
                }

                AddS(tcpcl.Client.RemoteEndPoint.ToString(), tcpcl); /* Here we're calling the delegate in order to add the new server to the main window server list. */

                this.Close();                                        /* After the server connection, the window will close "automatically" */
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
Exemplo n.º 12
0
 public override void Receive()
 {
     while (_client.Connected)
     {
         try
         {
             string message = SocketCommunication.GetMessage(_client.Client);
             QueueCommand(message);
         }
         catch (Exception e) // handle exception
         {
             Logger.Log(e.Message);
             _client.Close();
             ServerHandler?.Players.Remove(this);
             ServerHandler?.MatchmakingQueue.Remove(this);
             GameHandler?.Players.Remove(this);
             _receiveThread.Join();
         }
     }
 }
Exemplo n.º 13
0
        /// <summary>
        /// Connects/Starts a client
        /// </summary>
        public bool Start()
        {
            try
            {
                // Read account credentials
                _credentials = CredentialReader.ReadCredentials("RediParams.xml");

                if (!CheckParameterValidity())
                {
                    return(false);
                }

                // Create TCP Request
                _rediSocketConnection = new SocketCommunication(new Queue(), _credentials.Username,
                                                                _credentials.Password, _credentials.IpAddress, Convert.ToInt32(_credentials.Port), _logger);

                _rediSocketConnection.SendMessage += DataRecieved;
                _rediSocketConnection.ErrorInTcp  += new SocketCommunication.ConnectionError(RediSocketConnectionErrorInTcp);

                _isConnected = true;
                _rediSocketConnection.Connect();

                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Session is available.", _type.FullName, "Start");
                }

                if (LogonArrived != null)
                {
                    LogonArrived(_marketDataProviderName);
                }

                return(true);
            }
            catch (Exception exception)
            {
                _logger.Error(exception, _type.FullName, "Start");
            }
            return(false);
        }
        /*
         * Listener for "mouse ups" in the "MouseArea box". Here we capture each mouse up event in MouseArea box
         * and we will send this event (mouse left/right up) toward the server actually connected.
         */
        private void MouseArea_MouseUp(object sender, MouseEventArgs e)
        {
            message msg = new message();

            try
            {
                if (targetServer != null && targetServer.Connected) /* If no server is actually connected, we have to sent nothing */
                {
                    /*
                     * Here we have to Identify which mouse button has been released. MouseEventArgs contains this kind of information.
                     */
                    if (e.Button == MouseButtons.Left)
                    {
                        msg.act.eventype = EVENTYPE.LEFT_UP;
                    }
                    else if (e.Button == MouseButtons.Right)
                    {
                        msg.act.eventype = EVENTYPE.RIGHT_UP;
                    }
                    else if (e.Button == MouseButtons.Middle)
                    {
                        msg.act.eventype = EVENTYPE.MIDDLE_UP;
                    }

                    msg.messType = messageType.ACTION; /* Type of message: mouse or keyboard action, that must be sent via SendInput by the Server. */

                    /*
                     * Here we send all data to the server via Socket.
                     */
                    byte[] buffer = SocketCommunication.rawSerialize(msg);        /*Raw Serialize: Struct Serialization*/
                    SocketCommunication.sendBufferToSocket(buffer, targetServer); /*Buffer sending*/
                }
            }
            catch (Exception ex) /*If some exception occurs, we will show a message with the Error Description*/
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }
Exemplo n.º 15
0
        public void ConstructorWhenModeIsNotValidShouldThrowException()
        {
            SocketCommunication testSocket;

            Assert.Throws <ArgumentException>(() => testSocket = new SocketCommunication("invalid"));
        }
Exemplo n.º 16
0
        public void ConstructortWhenModeIsNullShouldThrowException()
        {
            SocketCommunication testSocket;

            Assert.Throws <ArgumentNullException>(() => testSocket = new SocketCommunication((string)null));
        }
Exemplo n.º 17
0
 public override void Output(string msg) => SocketCommunication.SendMessage(msg, _client.Client);
        /*
         * Function of clipSender thread. This thread will stay blocked waiting for a condition variable set, performed by the main thread
         * when the user perform a copy/cut operation.
         */
        private void clipSenderFunction()
        {
            message msg = new message();

            byte[] data = null;

            while (enableClipSender)        /*This function runs until the Application is active or the user makes a click on StopServerButton.*/
            {
                try
                {
                    send.WaitOne();         /* Wait for a notification from the main thread */

                    if (!enableClipSender)  /* If the main thread has set this boolean to false, this thread will terminate here. */
                    {
                        break;
                    }

                    IPEndPoint remoteIpEndPoint = clientSocket.Client.RemoteEndPoint as IPEndPoint; /* IP address of the client actually connected */

                    msg.messType = messageType.REMOTE_COPY;                                         /* The operation to perform is a RemoteCopy! */

                    if (Clipboard.ContainsText())                                                   /* The clipboard contains text! */
                    {
                        String text = Clipboard.GetText();                                          /* Here we get the text copied in the clipboard */

                        data = Encoding.Unicode.GetBytes(text);                                     /* We have to get the byte array of the text, in order to send this through a socket. */

                        msg.cinf.ct = clipboardType.TEXT;                                           /* We are sending text! */
                    }
                    else if (Clipboard.ContainsImage())                                             /*The clipboard contains an Image!*/
                    {
                        Image img = Clipboard.GetImage();                                           /*We have to get the image object..*/

                        data = SocketCommunication.serialize(img);                                  /* and to serialize it! */

                        msg.cinf.ct = clipboardType.IMAGE;                                          /*The data is an Image*/
                    }
                    else if (Clipboard.ContainsAudio())                                             /* The clipboard contains an audio stream! */
                    {
                        Stream audio = Clipboard.GetAudioStream();                                  /*We have to get the stream object..*/

                        data = SocketCommunication.serialize(audio);                                /* and to serialize it! */

                        msg.cinf.ct = clipboardType.AUDIO;                                          /* The clipboard data is an audio stream! */
                    }
                    else if (Clipboard.ContainsFileDropList())                                      /* The clipboard contains files! */
                    {
                        string archPath = SocketCommunication.createArchive();                      /*This function creates an archive with all files in the clipboard*/

                        FileInfo fi = new FileInfo(archPath);                                       /* Object containing info about the archive */

                        if (fi.Length > 10 * 1024 * 1024)                                           /* If the zip size is more than 10 MB */
                        {
                            DialogResult confirmResult = MessageBox.Show("Sei davvero sicuro di voler trasferire più di 10 MB di dati?",
                                                                         "Conferma Trasferimento",
                                                                         MessageBoxButtons.YesNo); /* We have to show a confirm button, in order to avoid network overhead. */

                            if (confirmResult == DialogResult.No)                                  /* If the user doesn't want to transfer the file.. */
                            {
                                continue;                                                          /* We have to continue */
                            }
                        }

                        msg.cinf.ct = clipboardType.FILES;                      /* The clipboard data is a FileDropList! */

                        msg.cinf.size = (int)fi.Length;                         /* Size of the archive that is going to be sent */

                        using (clipClient = new TcpClient())                    /* Socket used to send clipboard data to server */
                        {
                            clipClient.Connect(remoteIpEndPoint.Address, 9999); /* We have to connect to the target server, port 9999 */

                            SocketCommunication.sendBufferToSocket(SocketCommunication.rawSerialize(msg), clipClient);

                            SocketCommunication.sendFileToSocket(clipClient, archPath);
                        }

                        File.Delete(archPath);

                        continue;
                    }
                    else
                    {
                        msg.cinf.ct = clipboardType.NO_VALID_DATA;

                        data = new byte[4];
                    }

                    if (data.Length > 10 * 1024 * 1024)             /* If the data size is more than 10 MB */
                    {
                        DialogResult confirmResult = MessageBox.Show("Sei davvero sicuro di voler trasferire più di 10 MB di dati?",
                                                                     "Conferma Trasferimento",
                                                                     MessageBoxButtons.YesNo); /* We have to show a confirm button, in order to avoid network overhead. */

                        if (confirmResult == DialogResult.No)                                  /* If the user doesn't want to transfer the file.. */
                        {
                            continue;                                                          /* We have to continue */
                        }
                    }

                    msg.cinf.size = data.Length;

                    using (clipClient = new TcpClient())
                    {
                        clipClient.Connect(remoteIpEndPoint.Address, 9999);

                        SocketCommunication.sendBufferToSocket(SocketCommunication.rawSerialize(msg), clipClient);      /*Struct Sending*/
                        SocketCommunication.sendChunks(clipClient, data);                                               /* Data sending */
                    }
                }
                catch (SocketException)     /* The exceptions that occurs will be catched here and the thread will not terminate! This thread has to remain active while the application ends */
                {
                    continue;
                }
                catch (IOException)
                {
                    continue;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
        /*
         * Function executed by the clip receiver thread.
         */
        private void clipReceiverFunction()
        {
            message msg;

            clipServer = new TcpListener(IPAddress.Any, 9998); /* Socket listening for clients connections. */
            clipServer.Start();                                /* The clip server starts */
            byte[] data;

            while (enableClipServer) /* This boolean is modified by the main window when the user perform a click on the StopServerButton */
            {
                try
                {
                    using (clipReceiver = clipServer.AcceptTcpClient())
                    {
                        /* Here we are receiving the message with the clipboard data type that we are going to receive */
                        data = SocketCommunication.receiveBufferFromSocket(clipReceiver);
                        msg  = SocketCommunication.rawDeserialize <message>(data);

                        /* If the message is not a remote paste message, there is an error, and we must throw an exception. */
                        if (msg.messType != messageType.REMOTE_PASTE)
                        {
                            throw new Exception("Wrong message format!");
                        }

                        switch (msg.cinf.ct)
                        {
                        case clipboardType.TEXT:                                                     /* We are going to receive text */

                            data = SocketCommunication.receiveChunks(clipReceiver, msg.cinf.size);   /* Here we set the clipboard with the text received, encoding the received bytes with unicode format. */

                            Invoke(new txtSet(Clipboard.SetText), Encoding.Unicode.GetString(data)); /* Here we set the clipboard with the received text */

                            break;

                        case clipboardType.IMAGE:                                                  /* We are going to receive an Image */

                            data = SocketCommunication.receiveChunks(clipReceiver, msg.cinf.size); /*Function that receives data, saving chuncks of 1024 Bytes*/

                            Image i = (Image)SocketCommunication.deserialize(data);                /* Received bytes deserialization. The received object is of type Image*/
                            Invoke(new imgSet(Clipboard.SetImage), i);                             /* Here We set the clipboard with the received Image */

                            break;

                        case clipboardType.FILES:                                                          /* FILES case. To sent multiple files, we have to compress all files in a zip Archive. Therefore, now we must unzip the received archive */

                            String path    = SocketCommunication.receiveFile(clipReceiver, msg.cinf.size); /* This function returns the path of the received archive */
                            String dirName = Path.Combine(path, "temp");                                   /* Here we create the path to the folder that will contain all files */

                            if (!Directory.Exists(dirName))                                                /*If this folder doesn't exist...*/
                            {
                                Directory.CreateDirectory(Path.Combine(dirName));                          /* we have to create it! */
                            }
                            else
                            {
                                Directory.Delete(dirName, true);                        /* The  directory already exists, and probably contains files...*/
                                Directory.CreateDirectory(dirName);                     /* so we have to delete the directory and to recreate it, in order to save memory. */
                            }

                            ZipFile.ExtractToDirectory(Path.Combine(path, "receivedArchive.zip"), dirName); /* We unzip the archive in the folder "ReceiveTemp" */

                            string[]         sc      = Directory.GetFileSystemEntries(dirName);             /*This functions returns a string array with the filenames of each element in the new folder*/
                            StringCollection strColl = new StringCollection();                              /* Clipboard.SetFileDropList requires a StringCollection object */

                            strColl.AddRange(sc);                                                           /* Here we add to strColl all strings contained in sc */

                            Invoke(new fileSet(Clipboard.SetFileDropList), strColl);                        /* We have to call this functions with invoke in order to set the main thread as clipboard owner */

                            break;

                        case clipboardType.AUDIO:

                            data = SocketCommunication.receiveChunks(clipReceiver, msg.cinf.size);      /*Function that receives data, saving chuncks of 1024 Bytes*/
                            Stream audio = (Stream)SocketCommunication.deserialize(data);               /* Received bytes deserialization. The received object is of type Stream*/
                            Invoke(new audioSet(Clipboard.SetAudio), audio);                            /* Here We set the clipboard with the received Audio stream */

                            break;
                        }
                    }
                }
                catch (SocketException)
                {
                    continue;
                }
                catch (IOException)
                {
                    continue;
                }
                catch (ObjectDisposedException)
                {
                    continue;
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }
        }
        /*
         * Server function. While main thread is waiting for user commands,
         * this thread is listening for client connection/commands and eventually will inject events in system queue.
         */
        private void listener_function()
        {
            message msg = new message();

            byte[] data;                    /*Byte array containing received data*/
            bool   breaker;                 /*Boolean variable to break out of the inner loop*/

            serverSocket.Start();           /*Initialization of server Socket*/
            MessageBox.Show("Server Is Listening!");

            while (connected)
            {
                try                                                                   /* This try/catch block is in the while loop in order to avoid the listener thread termination due to some exception */
                {
                    clientSocket = serverSocket.AcceptTcpClient();                    /*The server is waiting for a client connection*/

                    data = SocketCommunication.receiveBufferFromSocket(clientSocket); /* First thing, the client sends to the server the password */

                    string psw = Encoding.Unicode.GetString(data);                    /* Get the password string from the byte array received */

                    if (psw.CompareTo(password) == 0)                                 /* If the password is correct */
                    {
                        msg.messType = messageType.CONNECTION_ACCEPTED;               /* The server reply with a "ConnectionAccepted message" */
                    }
                    else /* If the password is wrong */
                    {
                        msg.messType = messageType.CONNECTION_REFUSED;/* The server reply with a "Connection Refused Message" */
                    }

                    SocketCommunication.sendBufferToSocket(SocketCommunication.rawSerialize(msg), clientSocket);

                    if (msg.messType == messageType.CONNECTION_REFUSED) /* If the password was wrong, we must not accept client messages. */
                    {
                        throw new Exception("Wrong Password");          /* Then we have to listen for a new connection, showing to the user the message "Wrong Password" */
                    }

                    /*
                     * Here we are showing to the user info about the client actually connected
                     */
                    Invoke(new editLabel(this.editLabel), new object[] { statusInfo, "CONNECTED WITH " + clientSocket.Client.RemoteEndPoint.ToString() });

                    this.target = true;

                    breaker = true; /* While the client is still active, we have to receive client messages. Breaker = false only if the client send to the server a "Disconnect" message */

                    while (breaker)
                    {
                        data = SocketCommunication.receiveBufferFromSocket(clientSocket); /* Wait for a client message */
                        msg  = SocketCommunication.rawDeserialize <message>(data);        /* Deserialization of the received byte array */

                        switch (msg.messType)                                             /* We have to check which message has been received */
                        {
                        case messageType.ACTION:                                          /* We received a message whith an input which has to be sent to the system queue */

                            inputSend(msg.act);                                           /* Function that inject the input in the system */

                            break;

                        case messageType.DISCONNECT:                                                            /* We received a "Disconnect" message */
                            this.clientSocket.Close();                                                          /* We have to close the TcpClient on which we are receiving the messages */
                            this.target = false;                                                                /* Obviously this server isn't longer the target! */

                            Invoke(new editLabel(this.editLabel), new object[] { statusInfo, "DISCONNECTED" }); /* The server status is now "DISCONNECTED" */
                            Invoke(new editLabel(this.editLabel), new object[] { targetInfo, "FALSE" });        /* And this server is not longer the target */

                            breaker = false;                                                                    /* We have to break out from the inner loop in order to accept another client connection. */

                            break;

                        case messageType.TARGET_CHANGED:        /* This server is not longer the target, but the client is still connected */
                            this.target = false;

                            Invoke(new editLabel(this.editLabel), new object[] { targetInfo, "FALSE" });        /* This server is not longer the target */

                            break;

                        case messageType.TARGET:                /* This server is now the target! */
                            this.target = true;

                            Invoke(new editLabel(this.editLabel), new object[] { targetInfo, "TRUE" });

                            break;
                        }
                    }
                }
                catch (SocketException se)
                {
                    if (se.ErrorCode == 123456789) /* If the error code is 123456789, the other side of the connection has probably chashed. Then we have to close the actual connection and to wait for a new client connection */
                    {
                        this.clientSocket.Close(); /* We have to close the socket (due to the crashing of the other connection side) */
                        this.target = false;       /* And obviously this server is not longer the target. */

                        /*
                         * We have also to update the info to show to the user this server is not longer connected.
                         */
                        Invoke(new editLabel(this.editLabel), new object[] { statusInfo, "DISCONNECTED" });
                        Invoke(new editLabel(this.editLabel), new object[] { targetInfo, "FALSE" });

                        breaker = false;
                    }
                    continue;
                }
                catch (IOException)
                {
                    continue;
                }
                catch (ObjectDisposedException)
                {
                    continue;
                }
                catch (Exception except)
                {
                    MessageBox.Show(except.Message.ToString());
                }
            }
        }
        /*
         * Function of clipSender thread. This thread will stay blocked waiting for a condition variable set, performed by the main thread
         * when the user makes a double click on a server.
         */
        private void clipSenderFunction()
        {
            byte[] data;

            while (true) /*This function runs until the Application is active.*/
            {
                try
                {
                    Invoke(new makeInvisible(makeInvisible), remotePasteProgressBar);                     /* If a remote paste progress bar is visible, we have to make it invisible */

                    send.WaitOne();                                                                       /*Wait for a notification from the main thread*/

                    Invoke(new makeVisible(makeVisible), remotePasteProgressBar);                         /* Because we have to send data toward the targetServer, we show the progressBar to inform the user on the transfer */

                    IPEndPoint remoteServerIpEndPoint = targetServer.Client.RemoteEndPoint as IPEndPoint; /*Get ip address of the server actually connected*/

                    message msg = new message();

                    msg.messType = messageType.REMOTE_PASTE;       /* The operation to perform is a remote paste! */

                    if (Clipboard.ContainsText())                  /* The clipboard contains text! */
                    {
                        String text = Clipboard.GetText();         /* Here we get the text copied in the clipboard */

                        data = Encoding.Unicode.GetBytes(text);    /* We have to get the byte array of the text, in order to send this through a socket. */

                        msg.cinf.ct   = clipboardType.TEXT;        /* We are sending text! */
                        msg.cinf.size = data.Length;               /* We have to sent even the amount of text bytes in order to receive the whole array */
                    }
                    else if (Clipboard.ContainsImage())            /*The clipboard contains an Image!*/
                    {
                        Image img = Clipboard.GetImage();          /*We have to get the image object..*/

                        data = SocketCommunication.serialize(img); /* and to serialize it! */

                        msg.cinf.ct   = clipboardType.IMAGE;       /*The data is an Image*/
                        msg.cinf.size = data.Length;
                    }
                    else if (Clipboard.ContainsAudio())              /* The clipboard contains an audio stream! */
                    {
                        Stream audio = Clipboard.GetAudioStream();   /*We have to get the stream object..*/

                        data = SocketCommunication.serialize(audio); /* and to serialize it! */

                        msg.cinf.ct   = clipboardType.AUDIO;         /* Tha clipboard data is an audio stream! */
                        msg.cinf.size = data.Length;
                    }
                    else if (Clipboard.ContainsFileDropList())                 /* The clipboard contains files! */
                    {
                        string archPath = SocketCommunication.createArchive(); /*This function creates an archive with all files in the clipboard*/

                        FileInfo fi = new FileInfo(archPath);                  /* Object containing info about the archive */

                        if (fi.Length > 10 * 1024 * 1024)                      /* If the zip size is more than 10 MB */
                        {
                            DialogResult confirmResult = MessageBox.Show("Sei davvero sicuro di voler trasferire più di 10 MB di dati?",
                                                                         "Conferma Trasferimento",
                                                                         MessageBoxButtons.YesNo); /* We have to show a confirm button, in order to avoid network overhead. */

                            if (confirmResult == DialogResult.No)                                  /* If the user doesn't want to transfer the file.. */
                            {
                                continue;                                                          /* We have to continue */
                            }
                        }

                        msg.cinf.ct   = clipboardType.FILES;                              /* The clipboard data is a FileDropList! */
                        msg.cinf.size = (int)fi.Length;                                   /* Size of the archive that is going to be sent */

                        using (TcpClient clientSendData = new TcpClient())                /*Socket used to send clipboard data to server */
                        {
                            clientSendData.Connect(remoteServerIpEndPoint.Address, 9998); /* We have to connect to the target server, port 9998 */

                            SocketCommunication.sendBufferToSocket(SocketCommunication.rawSerialize(msg), clientSendData);
                            SocketCommunication.sendFileToSocket(clientSendData, archPath);

                            clientSendData.Close();
                        }

                        continue;
                    }
                    else
                    {
                        msg.cinf.ct = clipboardType.NO_VALID_DATA;
                        data        = new byte[4];
                    }

                    if (data.Length > 10 * 1024 * 1024) /* If the clipboard data is bigger than 10 MB */
                    {
                        DialogResult confirmResult = MessageBox.Show("Sei davvero sicuro di voler trasferire più di 10 MB di dati?",
                                                                     "Conferma Trasferimento",
                                                                     MessageBoxButtons.YesNo); /* We have to show a confirm button, in order to avoid network overhead. */

                        if (confirmResult == DialogResult.No)                                  /* If the user doesn't want to transfer the file.. */
                        {
                            continue;                                                          /* We have to continue */
                        }
                    }

                    using (TcpClient clientSendData = new TcpClient())                                                 /*Socket used to send clipboard data to server */
                    {
                        clientSendData.Connect(remoteServerIpEndPoint.Address, 9998);                                  /* We have to connect to the target server, port 9998 */

                        SocketCommunication.sendBufferToSocket(SocketCommunication.rawSerialize(msg), clientSendData); /* Struct Sending */
                        SocketCommunication.sendChunks(clientSendData, data);                                          /* Data sending */

                        clientSendData.Close();
                    }
                }
                catch (SocketException) /* The exceptions that occurs will be catched here and the thread will not terminate! This thread has to remain active while the application ends */
                {
                    continue;
                }
                catch (IOException)
                {
                    continue;
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }
        }
        /*
         * Function that receives the clipboard data and sets the client clipboard with the received data.
         */
        public void remoteCopy(TcpClient clipClient)
        {
            message msg;

            /*
             * Here we receive the struct that contains the data type that is going to arrive.
             */
            byte[] data = SocketCommunication.receiveBufferFromSocket(clipClient);
            msg = SocketCommunication.rawDeserialize <message>(data);

            /*
             * If we do not receive a messageType == remote_copy, there is an error!
             */
            if (msg.messType != messageType.REMOTE_COPY)
            {
                throw new Exception("Formato messaggio copia errato.");
            }

            switch (msg.cinf.ct)
            {
            case clipboardType.TEXT:                                                 /*The clipboard data is text*/

                data = SocketCommunication.receiveChunks(clipClient, msg.cinf.size); /*Function that receives data, saving chuncks of 1024 Bytes*/

                /* We have to call this functions with an invoke in order to set the main thread as clipboard owner */
                Invoke(new txtSet(Clipboard.SetText), Encoding.Unicode.GetString(data));     /* Here we set the clipboard with the text received, encoding the received bytes with unicode format. */

                break;

            case clipboardType.IMAGE:                                                /* The clipboard data is an Image */

                data = SocketCommunication.receiveChunks(clipClient, msg.cinf.size); /*Function that receives data, saving chuncks of 1024 Bytes*/

                Image i = (Image)SocketCommunication.deserialize(data);              /* Received bytes deserialization. The received object is of type Image*/

                Invoke(new imgSet(Clipboard.SetImage), i);                           /* Here We set the clipboard with the received Image */

                break;

            case clipboardType.FILES:                                                        /* FILES case. To sent multiple files, we have to compress all files in a zip Archive. Therefore, now we must unzip the received archive */

                String path    = SocketCommunication.receiveFile(clipClient, msg.cinf.size); /* This function returns the path of the received archive */
                String dirName = Path.Combine(path, "ReceiveTemp");                          /* Here we create the path to the folder that will contain all files */

                if (!Directory.Exists(dirName))                                              /*If this folder doesn't exist...*/
                {
                    Directory.CreateDirectory(dirName);                                      /* we have to create it! */
                }
                else
                {
                    Directory.Delete(dirName, true);     /* The  directory already exists, and probably contains files...*/
                    Directory.CreateDirectory(dirName);  /* so we have to delete the directory and to recreate it, in order to save memory. */
                }

                ZipFile.ExtractToDirectory(Path.Combine(path, "receivedArchive.zip"), dirName); /* We unzip the archive in the folder "ReceiveTemp" */
                File.Delete(Path.Combine(path, "receivedArchive.zip"));                         /*Then we delete the received zip, in order to save memory.*/

                string[]         sc      = Directory.GetFileSystemEntries(dirName);             /*This functions returns a string array with the filenames of each element in the new folder*/
                StringCollection strColl = new StringCollection();                              /* Clipboard.SetFileDropList requires a StringCollection object */

                strColl.AddRange(sc);                                                           /* Here we add to strColl all strings contained in sc */

                Invoke(new fileSet(Clipboard.SetFileDropList), strColl);                        /* We have to call this functions with an invoke in order to set the main thread as clipboard owner */

                break;

            case clipboardType.AUDIO:                                                /* The clipboard data is an audio stream. */

                data = SocketCommunication.receiveChunks(clipClient, msg.cinf.size); /*Function that receives data, saving chuncks of 1024 Bytes*/
                Stream audio = (Stream)SocketCommunication.deserialize(data);        /* Received bytes deserialization. The received object is of type Stream*/
                Invoke(new audioSet(Clipboard.SetAudio), audio);                     /* Here We set the clipboard with the received Audio stream */

                break;

            case clipboardType.NO_VALID_DATA:                                           /*If the clipboard doesn't contain a valid data format, we receive this message.*/

                data = SocketCommunication.receiveChunks(clipClient, msg.cinf.size);

                break;
            }
        }