SSE554Project3-DavidPage

=David's Project =
 * Client Instant Messenger Application **


 * 3. David's Project **

The last project for SSE 554 is a team project that shows our knowledge of C# programming. Les Laurell and I teamed up for project 3 and we discussed what we felt the project should cover to prove our knowledge. We concluded that a threaded application that used a TCP connection to send encrypted messages. With the basic outline we decided to create an Instant Messenger application.
 * Introduction **

The Instant Messenger project was broken into two pieces; the client application that the users would use to send and reactive messages, and the server application that would receive the message and send it out to the appropriate user. I chose to do the client application and Les chose to create the server application.
 * Overview **

I made myself a list of components that the client application will need that is shown below: //Listening Thread// – A thread is needed that listens over the TCP port for the sent messages. //Events// – An event should be used in the listening thread that is raised when the message is received by the application to decrypt. //Send Method// – A method that performs the task of sending the data over a TCP port to the server. //Encryption// – A class that encrypts the data to be sent and decrypts the data that is received by the client application. //Registry// – A registry key should be used in the encryption to encrypt and decrypt the message.

The list above also depicts the order that I chose to develop the application. It became very apparent that I would need to use two computers in order to test and debug the application. I used the same application I created on my main development computer and compiled it on the other computer in order to do this.

Because this application runs on the client's computers the same program will run on the sending computer and the receiving computer. The server will act as the gateway and pass the data between the IP addresses.

The client instant messenger application needed a thread that’s purpose is to listen on the port the message is being sent from. Before I was able to send a message to the computer I first had to get the thread to end execution once the application was closed. I had trouble doing this but eventually found I just needed to set the thread up as a background thread before the thread is started. The thread object’s declaration is in the constructor of the from1 class so it can start as soon as the application is loaded. When declaring the thread object, I set it up to call the method ‘Listen’ that is in the same class that the thread is declared. Once the object has been setup the thread is started with the ‘Start’ keyword. The screenshot that shows the declaration, setup, and start of the thread is shown in the image below.
 * Threading **



When the thread is started it calls the ‘Listen’ method whose purpose is to listen for the message that is being sent to it from the server. This method should always be running while the application is running. In order to achieve this, an endless 'while' loop is used that is always set to true. This was done so when the TCP code that is used to listen to the port receives and processes the message, the thread’s ‘Listen’ method instantly goes back into its listening mode. The screenshot shows this and the ‘…’ section is the TCP section of this application that will be discussed in detail further in this document. The screenshot of this code is shown in the image below.

A TCP connection was used to send and receive data between the client instant messenger application and the server. I thought this was going to be the toughest part of the project and worked on it after I had the listening thread running. The rest of the components of the project all rely on the TCP section working properly so they can function.
 * TCP connection **

To send the message, I set up a masked text box for the user to write the messages text, a read only rich text box that displays the received message and message sent, and a button that invokes the send method. The send method first writes the message to the rich text box and scrolls the rich text box to the end so the rich text box scrolls with the sent messages. Then, inside the ‘try’ of a try/catch statement, a TCP client object is setup that contains the IP address of the server and the port that the message is being sent on. My debug server’s IP address was 192.168.0.10 and the port I used was from the example in the book which was port 2112. After that is setup the network stream is setup with a call to the TCP client object’s ‘GetStream’ method. The data is then encrypted, whose process is discussed later, and packaged as an ASCII byte array into a byte array named ‘sendBytes’. The created network stream object sends the data with a call to its ‘Write’ method which contains the byte array, the start size of the array to send, and the total size of the array’s length. Then the network stream’s object is closed along with the TCP client object. This code is depicted in the image below. A screen shot of the application that has just sent the message “test” is depicted below.
 * Sending TCP data **

The ‘catch’ is there to report any issues that may occur in the TCP connection. These can range from the server refusing the connection, an incorrect server IP address, to the sending computer not being connected to the network. If the ‘try’ is not successful the ‘catch’ writes the error to the rich text box. Once the ‘try/catch’ is finished the masked text box has its data cleared. The code for the catch as well as clearing the masked text box is depicted in the image below. A screen shot of the application writing the error to the rich text box is depicted below.

The receiving TCP data’s code is located in the thread’s ‘Listen’ method endless while loop. The IP address has to be set so it knows what IP address to accept the message from on that port. I set it up to accept the message from all IP addresses. Then I set it up to listen on port 2112. I set up the TCP listener object ‘TcpListener’ with this information when it is being declared. Then I set the TCP listener object to start listening. This is depicted by the screenshot of the code in the image below.
 * Receiving TCP Data **

Then I setup a TCP client object named ‘TcpClient’ that is used with to setup the network stream object ‘ns’. The network stream object is then used to setup the stream reader object ‘sr’. Once the stream reader object is set up it is set to read the data that is being sent to it until all of the data is read in that TCP message. This part of the TCP receiving code is depicted in the image below.

Then the ‘Invoke’ method in the thread calls the event with the result string which contains the received message. The 'Invoke' keyword is used because the thread is listening and is not apart of the GUI components this gives the thread the abality to send data to the GUI class. Then the TCP client and TCP listener are closed. That code that handles this and the delegate’s setup is depicted in the image below.

A screenshot of the application after it has received the message “test” is depicted below.

This application uses an event that is setup by the delegate. This even is raised from the ‘Invoke’ method inside the thread’s listen method after the data has been read from the TCP port. This raised event calls the method ‘UpdateDisplay’ with the ‘result’ string to be processed. The event that is raised by the ‘Invoke’ method, as well as the delegate ‘UpdateDiaplayDelegate’ are shown above. The method that this raised event calls is depicted in the code in the image below.
 * Events **

In this method an encrypt object is made, ‘E’ that is used to called its ‘encryptData’ method when appending text to the rich text box. This method takes the encrypted result and a Boolean of false and returns the data decrypted. After the message is appended to the rich text box the scroll is set to the cursor’s current location which is where it was just inserted.

The encryption was the most difficult process when creating this application. I though it was going to be easy because I had two encryption classes I created from the first project I did for this class I would just modify to work. The code would compile on both computers, only the vista computer would not error when using the class to generate the keys. In order to get the code to run on the different XP operating system computers, I had to modify it to put the section that’s creating the keys inside of a try/catch. A screenshot of the code is depicted in the image below.
 * Encryption **

When I had the code on one of the XP computers without encryption I could tell the encryption was working because it would display encrypted data as the message received. When a windows XP machine tried to send a message it would crash when the message was being encrypted. When that same application received an encrypted message, and tried to decrypt the message, it would also crash. The error happened when the application went to create the key’s and code in ‘CngKey.Create(CngAlgorithm.ECDiffieHellmanP256)’ would return a null value. I wrote about this on the MSDN form to report the bug to Microsoft. The form can be found on the following link: [] The information I submitted to the MSDN form is shown in the image below.

After I did this I starting thinking about other ways I could encrypt/decrypt the data. I chose to write my own encryption program using the ASCII table numbers to change the characters. This is a poor way to decrypt a message because the ASCII’s integer value is changed 13. When the user sends the message, the ASCII number has 13 removed form it. Because the first ASCII character that the C# program can store is 32 the character’s ASCII being converted will never be below 0 and will be another ASCII character that exists. The encryption class’s ‘encryptData’ method is called with the string of the data to encrypt and a ‘true’ Boolean if the data is to be encrypted. If the data is to be decrypted the ‘encryptData’ method is called with a ‘false’ Boolean. When creating the string to return from the method outside of the ‘for’ loop, I found I had to set the string to empty because a null character would mess the code up when building the return string as depicted in the image below.

When the encryption method is called, I set the string to return ‘convertMsg’ to be a cleared string, put the string sent to the method into a character array named ‘encryptArray’, get the registry key, and start the ‘for’ loop that loops through each character in the array. The method accepts the string to convert and a Boolean of 'true' or 'false'. If the Boolean is 'true' the sent string will be encrypted, if it is 'false' the sent string will be decrypted. The code that does that is depicted in the image below.

The ‘for’ loop then loops through each character in the array and if it needs to be encrypted, the registry key value is removed from the ASCII value of the character. As I stated earlier the ASCII characters that the keyboard can enter to the masked text box cannot be lower than 32 on the ASCII table. So removing 13 from that will always contain a legitimate ASCII value that can be converted to a string. If the character needs to be decrypted, the value of that ASCII character gets the key’s value added to it. Once this is complete, the string ‘convertMsg’ gets this character appended to it. Once the ‘for’ loop is done executing the method returns the converted string. The Boolean that is sent to the method is used to tell the method to encrypt or decrypt the sent string. The code that does this is depicted in the image below.

If I do not decrypt the received encrypted message “test”, the client application that receives that message encrypted displays the following image in the rich text box.

The registry in windows is used to store application data and keys. In this example I used the registry as a key to encrypt and decrypt characters. The key is gathered from the ‘getRegistryKey’ method that returns the registry key as an integer. First this method checks the registry on the local computer for the registry key. It does this by creating a ‘RegistryKey’ object that points to the local machine’s registry named ‘hklm’. Then it creates another ‘RegistryKey’ object from the local computer registry ‘hklm’ by opening the sub key for that registry object named ‘hkSoftware’. The ‘RegistryKey’ object ‘hkSoftware’ is then used to try to check for the key. This is done by creating another ‘RegistrKey’ object named ‘hkMyKey’ from the ‘hkSoftware’ object calling the ‘OpenSubKey’ method with the registry’s location name. If the key is not found, the ‘hkMyKey’ variable will be null. This is depicted in the example of code in the image below. Then an ‘if’ statement checks if ‘hkMyKey’ is null, if it is null a ‘Microsoft.Win32.RegistryKey’ variable is created named ‘MakeKey’. The variable ‘MakeKey’ sets it’s value by a call to the ‘CreateSubKey’ method with the string of the key’s registry name “IMkey”. Then the ‘MakeKey’ variable calls the ‘SetValue’ method with the “IMencrypt” name that points directly to the registry key and the number 13 which is the registry key’s value. The registry value ‘MakeKey’ is then closed. This is depicted in the image below.
 * Registry **

Finally simular to how it set the value, the a variable named ‘regKey’ is created with the ‘Microsoft.Win32.RegistryKey’ object. Then it is set up with the ‘CreateSubKey’ method. Instad of calling the ‘SetValue’ method with the string of the name of the registery key and the value of that key, the method ‘GetValu’ is called with the string that points to the key’s value name that holds the value. This is being done in the declaration of an integer named ‘key’. The integer ‘key’ is then returned form this method. The code that depicts this is shown in the image below.

This project forced me to try to trouble shoot issues that were caused by the version of .Net being used. Because the library did not exist on those platforms of .Net I managed to create a workaround that works to create a simple encryption process. It is not encrypted to extreme measures and could probably be “hacked” fairly easily. I did learn a good deal about how C# creates and uses threads and was surprised at how simple it was. I was also very surprised as to how easy it was to get the TCP code to work. The book helped a lot and any questions I could not figure out with the book, I was usually able to find the answer on the MSDN C# forms. I was worried about using the registry but after reading over it in the book and on MSDN I can confidentially use it now. The server portion of the project had issues and after discussing this with Les, we chose to turn in two versions of an Instant Messenger program. This was a good learning exercise for me to learn more complex programming in C# that I can apply to other object oriented programming languages.
 * Conclusion **

Project Home Next Section