Chat Facility
> Networking application using WPF and the .NET Framework
> My Hand-in for Concurrent Network Applications Module for University
Learn More
View On Github
Project Overview
We were tasked to make a chat facility which allows users to communicate across a network
Server Features
- > Set Max Number of Users
- > Set Number of Users to Play Pictionary
- > Console Output - Shows all data packets passed through server
- > Threading for each client
- > Automatically detects host and opens server on port 4444
- > Packets system - for sending different types of data through the server
- > Encryption and Security - Between Server and Client
Client Features
- > Connection form - connect to any specified ip and port
- > Easy to understand UI
- > Chat to multiple clients through "main chat"
- > Private Message clients
- > Chat dropdown box - allows for easy private messaging
- > Change nickname in real time
- > Play Pictionary - Graphical Game
Code Snippets / Screenshots
Server - Handling Clients
The Server utilises threads to be able to handle inputs from each of the clients while also listening for new connections simultaneously
The code below shows how while the server is running the main thread will listen for new connections, if its a valid connection it will
then offload this work to another thread to listen to packets this client may send.
while (serverRunning)
{
Socket clientSocket = tcpListener.AcceptSocket();
ConnectedClient newClient = new ConnectedClient(clientSocket);
if (connectedClients.Count < maxClients)
{
connectedClients.Add(newClient);
threads.Add(new Thread(() => { ClientMethod(connectedClients.Last()); }));
threads.Last().Start();
}
else
{
TcpSendDataToSpecificClient(newClient, new Packets.DisconnectPacket());
}
}
Server - Packets
From the code snippet above we can see an example of a DisconnectPacket to allow specific data to be sent from clients to the server
I created a packet system and methods for the server to send packets to all clients and specific clients. I have included the enum to show all
the packets I created for the application.
> All packets follow the same format therefore I will only show one example here the rest can be found on the projects github repo
public enum PacketType
{
ChatMessage,
PrivateMessage,
Nickname,
Disconnect,
Login,
KeyPacket,
ClientList,
GameConnectionPacket,
PictionaryChatMessage,
PictionaryPaint,
PictionaryClearCanvas,
PictionarySetupClient,
PictionaryWordToDraw,
PictionaryClientList
}
[Serializable()]
public class PrivateMessagePacket : Packet
{
private byte[] message;
private string targetUser;
public PrivateMessagePacket(byte[] message, string targetUser)
{
this.message = message;
this.targetUser = targetUser;
m_PacketType = PacketType.PrivateMessage;
}
public byte[] Message
{
get { return message; }
set { message = value; }
}
public string TargetUser
{
get { return targetUser; }
protected set { }
}
}
Server - Security
The way in which the client and server have a layer of security is by using RSACryptoServiceProvider keys, the clients have their
own keys and so does the server, upon loging into the server the client sends its key to the server and the server sends its key back,
this allows for a basic level of security between our client and server where we utilise the keys to encrypt and decrypt messages.
> The below snippet is from the servers response to a client connecting, it creates a new instance of this client and sends back a key upon login.
public ConnectedClient(Socket socket)
{
this.socket = socket;
readLock = new object();
writeLock = new object();
stream = new NetworkStream(socket);
writer = new BinaryWriter(stream);
reader = new BinaryReader(stream);
formatter = new BinaryFormatter();
rsaProvider = new RSACryptoServiceProvider();
publicKey = rsaProvider.ExportParameters(false);
privateKey = rsaProvider.ExportParameters(true);
}
public void Login(string nickname, IPEndPoint endPoint, RSAParameters publicKey)
{
this.nickname = nickname;
this.endPoint = endPoint;
clientKey = publicKey;
TcpSend(new Packets.KeyPacket(this.publicKey));
}
Client
The majority of the clients code is handling data, for example, taking data from a text box converting it to a valid packet and sending
it to the server because of this I will include more screenshots of the physical application as opposed to the code
The client has 3 main windows - The main interface, the connection form, and the pictionary game screen.
Pictionary
For the criteria of the project we needed to create a realtime graphical game for the users to play across the server,
I decided to recreate pictionary
To allow for a working game I created specific features to allow for a fun game:
- > Drawing with a pen
- > Changing the brush colour
- > Eraser tool
- > Clear canvas button
- > Chat for guessing and chatting
- > System to only send the item being drawn to the "drawer"
- > System to detect if the user has guessed correctly
A more in depth demonstration video was created for the project and I will be more than happy providing the video if requested.
The project has a lot more features which I am happy to discuss if needed.
I haven't posted in a while so here's something I made for my networking assignment. It draws in real-time to clients using a WPF inkcanvas. You can see the final project on my GitHub #gamedev #gameprogramming #csharp #pictionary#indiedev pic.twitter.com/EmvCdTWGYh
— Ryan (@RGoldsmith429) February 7, 2021