// ------------------------------------------------------------------------------------------ /// <summary> Funkcja wysyłająca wiadomość do określonego klienta. </summary> /// <param name="arguments"> Tablica argumentów (id/nazwa podłączonego klienta), wiadomość. </param> private void SendMessageCommand(string[] arguments) { int identifier = -1; ClientData client; try { if (int.TryParse(arguments[1], out identifier)) { client = GetClient(identifier); } else { client = GetClient(arguments[1]); } if (client == null) { throw new Exception(); } } catch (IndexOutOfRangeException) { UpdateUI("( ! ) Syntax Command is invalid. Missing <id/name> argument."); return; } catch (Exception) { UpdateUI("( ! ) Client with specified identifier, does not exist."); return; } try { string content = Tools.ConcatLines(arguments, 2, arguments.Length, " "); Message message = new Message(0, identifier, DateTime.Now, "", content); SendMessage(client, message); } catch (IndexOutOfRangeException) { UpdateUI("( ! ) Syntax Command is invalid. Missing <message> argument."); return; } catch (Exception) { return; } }
// ########################################################################################## /// <summary> Funkcja sprawdzająca poprawość polecenia zdalengo i egzekwująca jego wykonanie. </summary> /// <param name="message"> Paczka wiadomości z poleceniem zdalnym (komendą) klienta. </param> /// <param name="sender"> Klient wysyłający polecenie. </param> /// <returns> Informacja o poprawnym wykonaniu polecenia. </returns> private bool ExecuteClientCommand(Message message, ClientData sender) { string[] arguments = message.command.Split(' '); bool result = true; if (arguments.Length <= 0) { result = false; } else if (arguments[0].Length <= 0) { result = false; } else if (arguments[0] == "/config") { ConfigureCommand(message.message, sender); } else if (arguments[0] == "/list") { SendListCommand(sender); } else if (arguments[0][0] == '/') { UpdateUI("( ! ) Syntax Command is invalid."); } else { result = false; } return(result); }
// ########################################################################################## /// <summary> Funkcja sprawdzająca poprawość polecenia zdalengo i egzekwująca jego wykonanie. </summary> /// <param name="message"> Paczka wiadomości z poleceniem zdalnym (komendą) serwera. </param> /// <returns> Informacja o poprawnym wykonaniu polecenia. </returns> private bool ExecutServerCommand(Message message) { string[] arguments = message.command.Split(' '); bool result = true; if (arguments.Length <= 0) { result = false; } else if (arguments[0].Length <= 0) { result = false; } else if (arguments[0].ToLower() == "/config") { ConfigureClientCommand(message.message); } else if (arguments[0].ToLower() == "/list") { ReadListCommand(message.message); } else if (arguments[0].ToLower() == "/disconnect") { InvokeUI(FuncShutDown); } else if (arguments[0][0] == '/') { UpdateUI("( ! ) Syntax Command is invalid.", MessageModifier.SERVER); } else { result = false; } return(result); }
// ------------------------------------------------------------------------------------------ /// <summary> Funkcja wysyłająca wiadomość do określonego podłączonego. </summary> /// <param name="client"> Podłączony klient. </param> /// <param name="message"> Wiadomość wysyłana do klienta. </param> private void SendMessage(ClientData client, Message message) { Socket socket = client.Socket; // Szyfrowanie wiadomości do wsyłania if (client.Encrypted) { ICrypt encryptionServices = null; switch (client.CryptType) { case CryptType.RSA: encryptionServices = encryptionServicesRSA; break; case CryptType.ElGamal: encryptionServices = encryptionServicesElGamal; break; } message.Encrypt(encryptionServices, client.Key); } byte[] buffer = Encoding.ASCII.GetBytes(message.ToString()); Console.Write(message.ToString()); AsyncCallback sender = new AsyncCallback(SendCallback); socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, sender, client); client.BeginReciveMessages(); }
// ------------------------------------------------------------------------------------------ /// <summary> Funkcja wysyłająca wiadomość do podłączonego klienta lub grupy. </summary> /// <param name="message"> Wiadomość wysyłana do klienta. </param> private void SendBroadcast(string message) { if (srvClients == null) { return; } foreach (ClientData client in srvClients) { Message newMessage = new Message(0, client.Identifier, DateTime.Now, "", message); SendMessage(client, newMessage); } }
// ------------------------------------------------------------------------------------------ /// <summary> Funkcja odbierająca wiadomości z serwera. </summary> private void LoopRecive() { if (cliSocket == null) { return; } int refuseAttempts = 0; while (cliSocket.Connected) { try { byte[] buffer = new byte[BufferSize]; int bufferSize = cliSocket.Receive(buffer); byte[] message = new byte[bufferSize]; if (bufferSize == 0) { LoopReconnect(true, ref refuseAttempts); continue; } else { refuseAttempts = 0; } Array.Copy(buffer, message, bufferSize); Message newMessage = Message.ReadMessage(Encoding.ASCII.GetString(message)); // DECRYPTION Console.WriteLine(newMessage.ToString()); newMessage.Decrypt(encryptionServices, encryption); bool executed = ExecutServerCommand(newMessage); if (!executed) { int senderId = newMessage.senderId; int reciverId = newMessage.reciverId; string[] senders = (from c in Clients where c[0] == senderId.ToString() select c[1]).ToArray(); string sendDate = newMessage.sendDate.ToString(); UpdateUI( sendDate + " " + (senders.Length > 0 ? senders[0] : senderId.ToString()) + Environment.NewLine + newMessage.message, MessageModifier.INCOMING ); } } catch (SocketException exc) { UpdateUI(string.Format(_messageConnectionRefused, Environment.NewLine, exc.ToString()), MessageModifier.SERVER); ShutDown(); return; } } }
// ------------------------------------------------------------------------------------------ /// <summary> Funkcja wysyłająca do klienta listę podłączonych klientów. </summary> /// <param name="sender"> Klient do którego ma zostać przesłana lista. </param> private void SendListCommand(ClientData sender) { string[][] clients = GetClientList(sender); string content = ""; string line = ""; for (int i = 0; i < clients.Length; i++) { line = clients[i][0] + " " + clients[i][1] + " " + clients[i][2]; content += (line + (i < clients.Length - 1 ? Environment.NewLine : "")); } Message newMessage = new Message(0, sender.Identifier, DateTime.Now, "/list", content); SendMessage(sender, newMessage); }
// ########################################################################################## /// <summary> Funkcja wykonująca wywołanie polecenia z okna wiadomości klienta. </summary> /// <param name="message"> Polecenie z okna wiadomości klienta. </param> public void SendCommand(string message) { bool executed = ExecutClientCommand(message); DateTime sendDate = DateTime.Now; string[] recivers = (from c in Clients where c[0] == Sender.ToString() select c[1]).ToArray(); if (!executed) { UpdateUI( sendDate.ToString() + " " + (recivers.Length > 0 ? recivers[0] : Sender.ToString()) + Environment.NewLine + message, MessageModifier.OUTGOING ); Message newMessage = new Message(identifier, Sender, sendDate, "", message); SendMessage(newMessage); } }
// ------------------------------------------------------------------------------------------ /// <summary> Funkcja wysyłająca do serwera dane konfiguracyjne klienta. </summary> private void ConfigureServerCommand() { string publicKey = ""; // Konfiguracja publicznego klucza szyfrującego wiadomości dla serwera. if (cryptType != CryptType.None) { publicKey = encryptionServices.GetPublicKey(); } string content = Tools.ConcatLines( new string[] { Username, ((int)this.cryptType).ToString(), publicKey, "<end>" }, 0, 4, Environment.NewLine); Message newMessage = new Message(identifier, 0, DateTime.Now, "/config", content); SendMessage(newMessage); }
// ------------------------------------------------------------------------------------------ /// <summary> Funkcja wysyłająca wiadomość do podłączonego serwera. </summary> /// <param name="message"> Wiadomość wysyłana do serwera. </param> public void SendMessage(Message message) { if (cliSocket == null) { return; } if (!cliSocket.Connected) { return; } // ENCRYPTION if (encryption) { message.Encrypt(encryptionServices, serverPublicKey); } byte[] buffer = Encoding.ASCII.GetBytes(message.ToString()); cliSocket.Send(buffer); }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------ /// <summary> Funkcja konfigurująca serwera z danymi klienta. </summary> /// <param name="message"> Wiadomość konfiguracyjna od klienta. </param> /// <param name="sender"> Klient wysyłający polecenie. </param> private void ConfigureCommand(string message, ClientData sender) { string[] arguments = Tools.ReadLines(message); int ctpye = 0; bool encrypted = false; string publicKey = ""; // Pobranie publicznego klucza szyfrującego od klienta. try { sender.Name = arguments[0]; int.TryParse(arguments[1], out ctpye); sender.CryptType = (CryptType)ctpye; sender.Key = arguments[2]; } catch (IndexOutOfRangeException) { /* Not transferred all required data */ } catch (Exception) { /* Unknown Data Error Exception */ } // Konfiguracja publicznego klucza szyfrującego wiadomości do wsyłania do klienta. if (((CryptType)ctpye) != CryptType.None) { encrypted = true; } if (encrypted && arguments[2] != "") { switch (sender.CryptType) { case CryptType.RSA: publicKey = encryptionServicesRSA.GetPublicKey(); break; case CryptType.ElGamal: publicKey = encryptionServicesElGamal.GetPublicKey(); break; } } UpdateUI("( i ) Updated Client data with ID: " + sender.Identifier.ToString()); UpdateUI(" Client UserName is: " + sender.Name); UpdateUI(" Client is using Cryptograpyh: " + (encrypted ? "Yes" : "No")); if (encrypted) { UpdateUI(" Client public Key is: " + sender.Key); } string content = Tools.ConcatLines( new string[] { Username, sender.Identifier.ToString(), publicKey, "<end>" }, 0, 3, Environment.NewLine); Message newMessage = new Message(0, sender.Identifier, DateTime.Now, "/config", content); SendMessage(sender, newMessage); // Konfiguracja publicznego klucza szyfrującego od klienta try { if (encrypted && arguments[2] != "") { sender.Encrypted = true; } } catch { /* NOT CRYPTED */ } UpdateClientList(); }
// ------------------------------------------------------------------------------------------ /// <summary> Funkcja odbierająca wiadomość od klienta. </summary> /// <param name="asyncResult"> Podłączony klient. </param> private void ReciveCallback(IAsyncResult asyncResult) { try { ClientData client = (ClientData)asyncResult.AsyncState; Socket socket = client.Socket; int bufferSize = socket.EndReceive(asyncResult); byte[] buffer = new byte[bufferSize]; if (bufferSize == 0) { LoopReconnect(asyncResult, client); return; } else { client.ReconnectAttempt = 0; } Array.Copy(client.Buffer, buffer, bufferSize); Message newMessage = Message.ReadMessage(Encoding.ASCII.GetString(buffer)); // Deszyfrowanie wiadomości po otrzymaniu. if (client.Encrypted) { ICrypt encryptionServices = null; switch (client.CryptType) { case CryptType.RSA: encryptionServices = encryptionServicesRSA; break; case CryptType.ElGamal: encryptionServices = encryptionServicesElGamal; break; } newMessage.Decrypt(encryptionServices, client.Encrypted); } bool executed = ExecuteClientCommand(newMessage, client); if (!executed) { int senderId = newMessage.senderId; int reciverId = newMessage.reciverId; string sendDate = newMessage.sendDate.ToString(); if (reciverId == 0) { UpdateUI(sendDate + " [ " + client.Name + " ] " + Environment.NewLine + newMessage.message); } else { SendMessage(GetClient(reciverId), newMessage); } } client.BeginReciveMessages(); } catch (NullReferenceException) { /* socket is currently NULL */ } catch (ObjectDisposedException) { /* socket is currently NULLable */ } catch (SocketException) { /* socket is currently Disconected */ } }
// ------------------------------------------------------------------------------------------ /// <summary> Funkcja wysyłająca do serwera prośbę o przesłanie listy podłączonych klientów. </summary> private void RequestListCommand() { Message newMessage = new Message(identifier, 0, DateTime.Now, "/list", ""); SendMessage(newMessage); }