/// <summary> /// Function to send data to the client. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ButtonSendMessage_Click(object sender, EventArgs e) { const string NULLDATAERRORMESSAGE = "Field cannot be left empty"; //If there is no message to send, display an error message in the ErrorProvider ClassLibrary.CheckTextBoxNotNull(TextBoxTypeMessage, ErrorProvider); if (ErrorProvider.GetError(TextBoxTypeMessage) == NULLDATAERRORMESSAGE) { return; } //Encrypt the message and transmit it string encryptedMessage = ClassLibrary.SymmetricEncryptDecrypt(TextBoxTypeMessage.Text, symmetricKey); byte[] bt = Encoding.UTF8.GetBytes(encryptedMessage); try { connectedClient.Client.Send(bt); } catch (Exception ex) { MyMessageBox.ShowMessage(ex.ToString()); return; } //Display the text in the list box ListBoxChat.Items.Add(staffMember.StaffFirstName + ": " + TextBoxTypeMessage.Text + Environment.NewLine); TextBoxTypeMessage.Clear(); }
private void ButtonSendMessage_Click(object sender, EventArgs e) { const string NULLDATAERRORMESSAGE = "Field cannot be left empty"; ClassLibrary.CheckTextBoxNotNull(TextBoxTypeMessage, ErrorProvider); //As long as the user has some sort of input in the textbox, the message will send if (ErrorProvider.GetError(TextBoxTypeMessage) == NULLDATAERRORMESSAGE) { return; } //Encrypt the message string encryptedMessage = ClassLibrary.SymmetricEncryptDecrypt(TextBoxTypeMessage.Text, symmetricKey); //Encode the message and send it serverStream.Write(Encoding.UTF8.GetBytes(encryptedMessage), 0, Encoding.UTF8.GetByteCount(encryptedMessage)); serverStream.Flush(); //Display the message to the rich text box sbSend.Clear(); sbSend.Append(student.StudentFirstName); sbSend.Append(": "); sbSend.Append(TextBoxTypeMessage.Text); sbSend.Append(Environment.NewLine); RichTextBoxChatWindow.SelectionColor = Color.Blue; RichTextBoxChatWindow.AppendText(sbSend.ToString()); TextBoxTypeMessage.Clear(); }
private void SendStudentID() { string sID = ClassLibrary.SymmetricEncryptDecrypt(student.StudentID, symmetricKey); serverStream.Write(Encoding.UTF8.GetBytes(sID), 0, Encoding.UTF8.GetByteCount(sID)); serverStream.Flush(); }
//Staff name must be sent before the client and server begin chatting, //so the users know who they're communicating with private void SendStaffName() { string encryptedMessage = ClassLibrary.SymmetricEncryptDecrypt(staffMember.StaffFirstName, symmetricKey); byte[] bt = Encoding.UTF8.GetBytes(encryptedMessage); try { connectedClient.Client.Send(bt); } catch (Exception ex) { MyMessageBox.ShowMessage("Failed to send staff first name: " + ex.ToString()); } }
/// <summary> /// Callback function called when data is received on the socket /// </summary> /// <param name="ar"></param> public void OnReceive(IAsyncResult ar) { string content = string.Empty; int bytesRead; // Retrieve the state object and the handler socket //from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState; Socket clientSocket = state.workSocket; if (clientSocket.Connected) { // Read data from the client socket. try { bytesRead = clientSocket.EndReceive(ar); if (bytesRead > 0) { if (!symmetricKeyReceived) { byte[] temp = state.buffer; int i = temp.Length - 1; while (temp[i] == 0) { --i; } // now data[i] is the last non-zero byte byte[] receivedData = new byte[i + 1]; Array.Copy(temp, receivedData, i + 1); //Get the symmetric key after decrypting it using RSA byte[] decryptedKey = rsa.Decrypt(receivedData, false); string decryptedKeyString = Convert.ToBase64String(decryptedKey); symmetricKey = decryptedKeyString; symmetricKeyReceived = true; SendStaffName(); clientSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(OnReceive), state); return; } // There might be more data, so store the data received so far. state.sb.Remove(0, state.sb.Length); state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead)); if (!studentNameReceived) { string encryptedStudentID = state.sb.ToString(); string sID = ClassLibrary.SymmetricEncryptDecrypt(encryptedStudentID, symmetricKey); try { SqlConnector db = new SqlConnector(); List <StudentModel> listStudents = db.GetStudent_ByStudentID(sID); connectedStudent = listStudents[0]; } catch { MyMessageBox.ShowMessage("Access to the database failed."); return; } SetTextBoxStudentName(); studentNameReceived = true; clientSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(OnReceive), state); return; } // Display text in rich text box string received = state.sb.ToString(); content = ClassLibrary.SymmetricEncryptDecrypt(received, symmetricKey); SetText(content); clientSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(OnReceive), state); } else { //Disconnect request has 0 bytes. //So if 0 byte message detected: disable further communication. SetSendButton(false); SetTextBoxConnectionStatus(Color.Red); clientStream.Dispose(); clientStream.Close(); connectedClient.Client.Dispose(); connectedClient.Client.Close(); } } catch (SocketException socketException) { //WSAECONNRESET, the other side closed impolitely if (socketException.ErrorCode == 10054 || ((socketException.ErrorCode != 10004) && (socketException.ErrorCode != 10053))) { // Complete the disconnect request. string remoteIP = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString(); string remotePort = ((IPEndPoint)clientSocket.RemoteEndPoint).Port.ToString(); this.ownerForm.DisconnectClient(remoteIP, remotePort); clientSocket.Close(); clientSocket = null; } } catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); } } }
/// <summary> /// A callback function triggered when data is received on the socket. /// </summary> /// <param name="ar"></param> public void OnReceive(IAsyncResult ar) { string content = string.Empty; //Retrieve the state object and the handler socket from the asynchronous state object state = (StateObject)ar.AsyncState; Socket handler = state.workSocket; int bytesRead; if (handler.Connected) { //Read data from the client socket try { bytesRead = handler.EndReceive(ar); if (bytesRead > 0) { //There might be more data, so store the data received so far state.sb.Remove(0, state.sb.Length); //Translate the bytes into a readable format state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead)); string s = state.sb.ToString(); //Before the server and client can begin chatting, the server must send its //public key over, the client then sends a generated symmetric key back, encrypted //using the public key. Then the server must send the staff member's name while //the client must send the student ID. if (!publicKeyReceived) { rsa = new RSACryptoServiceProvider(2048); //Save the public key received to rsa rsa.FromXmlString(state.sb.ToString()); SendSymmetricKey(); publicKeyReceived = true; //Continue to asynchronously receive data from the server handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(OnReceive), state); return; } if (!nameReceived) { SendStudentID(); string encryptedStaffName = state.sb.ToString(); staffName = ClassLibrary.SymmetricEncryptDecrypt(encryptedStaffName, symmetricKey); nameReceived = true; handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(OnReceive), state); return; } //Display text in TextBox string received = state.sb.ToString(); content = ClassLibrary.SymmetricEncryptDecrypt(received, symmetricKey); //Function used to display text in the rich text box. A delegate function //must be used as we're not on the main thread. SetText(content); handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(OnReceive), state); } else { //If no data is received, then an error has occured as null messages cannot be sent. MyMessageBox.ShowMessage("Error occured: no data was supplied."); } } catch (SocketException socketEx) { //WSAECONNRESET: if the other side closes impolitely //(they shut down the server or crash for some reason) //Cut the connection and reset everything if (socketEx.ErrorCode == 10054 || ((socketEx.ErrorCode != 10004) && (socketEx.ErrorCode != 10053))) { handler.Close(); SetTextBoxConnectionStatusBackgroundColour(Color.Red); SetSendButton(false); SetConnectButton(true); SetDisconnectButton(false); serverStream.Close(); server.Close(); nameReceived = false; publicKeyReceived = false; } } catch (Exception ex) { //Anyother unexpected error is displayed here MyMessageBox.ShowMessage(ex.Message); } } else { handler.Close(); } }