/* * 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); } }
/* * 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(); }
/* * 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); } }
/* * 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); } }
/* * 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*/ } }
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); } }
/* * 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()); } }
/* * 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); } } }
/* * 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); } } }