Esempio n. 1
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);
            }
        }
        /*
         * 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 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);
                }
            }
        }
        /*
         * 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;
            }
        }