Exemple #1
0
        static void Main(string[] args)
        {
            // Display logo
            ChatShell();

            TcpListener listner = null;
            // The server will be listening to the below port for client connections
            int port = 6969;

            try
            {
                // Listen for client connections on any ip address on above declared port
                listner = new TcpListener(IPAddress.Any, port);
                listner.Start();
                Console.WriteLine("ChatShell server started.");
                Console.WriteLine("Awaiting clients...");

                // Run on an infinite loop
                while (true)
                {
                    if (listner.Pending())
                    {
                        TcpClient client = default(TcpClient);
                        client = listner.AcceptTcpClient();

                        // Get username from client as a byte array and then encode to ASCII string;
                        byte[]        inStream      = new byte[100];
                        NetworkStream networkStream = client.GetStream();
                        int           bytesRead     = networkStream.Read(inStream, 0, inStream.Length);
                        string        recievedData  = Encoding.ASCII.GetString(inStream, 0, bytesRead);

                        //Decrypt data gotten from client
                        recievedData = encryptor.decrypt(recievedData);

                        //Get connection password and username (stored in client data)
                        string pass       = recievedData.Substring(0, 4);
                        string clientData = recievedData.Remove(0, 4);

                        //If invalid connection password block user and send error message
                        if (!pass.Equals("PASS"))
                        {
                            Console.ForegroundColor = ConsoleColor.Yellow;
                            Console.WriteLine($"Forceful connection declined!");
                            Console.ForegroundColor = ConsoleColor.White;

                            // Send an encoded and encrypted message to the client saying that the username alredy exists
                            byte[] outStream = Encoding.ASCII.GetBytes("Invalid client. Please use ChatShell to connect");
                            networkStream.Write(outStream, 0, outStream.Length);
                        }
                        // If user with the same username exists
                        else if (clients.ContainsKey(clientData))
                        {
                            Console.ForegroundColor = ConsoleColor.Yellow;
                            Console.WriteLine($"User with username {clientData} tried to connect. But was rejected as that username already exists");
                            Console.ForegroundColor = ConsoleColor.White;

                            // Send an encoded and encrypted message to the client saying that the username alredy exists
                            byte[] outStream = Encoding.ASCII.GetBytes(encryptor.encrypt("!error user-exists"));
                            networkStream.Write(outStream, 0, outStream.Length);
                        }
                        else
                        {
                            // Send a message to the client allowing the connection after encryption. Encrypted message is turned into a bye array when sending
                            byte[] outStream = Encoding.ASCII.GetBytes(encryptor.encrypt("!connect"));
                            networkStream.Write(outStream, 0, outStream.Length);

                            //Prevent network stream messages from overlapping
                            Thread.Sleep(10);

                            //Display message in server CLI
                            Console.BackgroundColor = ConsoleColor.DarkGreen;
                            Console.ForegroundColor = ConsoleColor.White;
                            Console.WriteLine($"{clientData} connected to the chat");
                            Console.BackgroundColor = ConsoleColor.Black;

                            //Broadcast message to other clients
                            broadcastMessage($"!rc {clientData} connected to the chat", clientData, false);

                            //Add new client to client list;
                            clients.Add(clientData, client);

                            // Send already connected user list to clients
                            if (clients.Count != 0)
                            {
                                broadcastMessage(getUserList(), clientData, false);
                            }

                            //Create ClientClass object and set variable values
                            ClientClass clientObject = new ClientClass();

                            clientObject.username = clientData;
                            clientObject.client   = client;

                            //Create new thread to handle client
                            Thread thread = new Thread(handleClient);
                            thread.Start(clientObject);
                        }
                    }
                }
            }catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            Console.ReadKey();
        }
Exemple #2
0
        // Method to handle a single client (will run on multiple threads for different clients)
        static void handleClient(object clientObject)
        {
            // Cast the recieved ClientClass object
            ClientClass recievedClientObject = (ClientClass)clientObject;

            // Get the TcpClient object and username from the ClientClass object
            TcpClient client   = recievedClientObject.client;
            string    username = recievedClientObject.username;

            try
            {
                string dataFromClient = null;

                // Until client sends a disconnecting command run this loop
                do
                {
                    // Recive data from the client using the network stream
                    byte[]        inStream      = new byte[4096];
                    NetworkStream networkStream = client.GetStream();
                    int           bytesRead     = networkStream.Read(inStream, 0, inStream.Length);
                    dataFromClient = Encoding.ASCII.GetString(inStream, 0, bytesRead);

                    // Decrypt the data taken from client
                    dataFromClient = encryptor.decrypt(dataFromClient);

                    // If the client doesnt send a disconnect command
                    if (!dataFromClient.Equals("!exit"))
                    {
                        // If the client wants to send a private message to another client
                        if (dataFromClient.StartsWith("!pm"))
                        {
                            Console.WriteLine($"{dataFromClient}");
                            broadcastPrivateMessage(dataFromClient);
                        }
                        //If the client message is public
                        else
                        {
                            Console.WriteLine($"{username}: {dataFromClient}");
                            broadcastMessage(dataFromClient, username, true);
                        }
                    }

                    // Exit loop after client sends disconnect command
                } while (!(dataFromClient.Equals("!exit") || dataFromClient == null));

                // After the client had disconnected

                // Remove the client from the hashtable
                clients.Remove(username);

                // Display message on server
                Console.BackgroundColor = ConsoleColor.Red;
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine($"{username} disconnected from the chat");
                Console.BackgroundColor = ConsoleColor.Black;

                // Broadcast to other clients in an encoded message that the client has disconnected
                broadcastMessage($"!dc {username} disconnected from the chat", username, false);

                // Send updated user list to clients if there are connected clients
                if (clients.Count != 0)
                {
                    broadcastMessage(getUserList(), username, false);
                }
            }
            catch (IOException e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                // Finally close the created TcpClient object
                if (client != null)
                {
                    client.Close();
                }
            }
        }