TheRyuzaki.Network v0.001 PreAlpha - Критика и оптимизация - C#
Формулировка задачи:
Client.cs
using System; using System.Collections.Generic; using System.Collections.Concurrent; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.IO; using System.Threading; namespace TheRyuzaki.Network { public class Client { public int build = 1; public Dictionary<string, object> Cl = new Dictionary<string, object>(); #region Обьявление ссылок на функции /// <summary> /// Ссылка на функцию вызываемую при завершении действий по подключению к серверу. /// </summary> public Action ConnectToServer_Completed = null; /// <summary> /// Ссылка на функцию вызываемую при получении текста от сервера. /// </summary> public Action<string> ReadLineToServer = null; /// <summary> /// Ссылка на функцию вызываемую при завершении отключения от сервера. /// </summary> public Action DisconnectServer_Completed = null; #endregion /// <summary> /// Класс для клиента по работе с сервером работающиго на TheRyuzaki.Network /// </summary> /// <param name="ip">IP Адрес до сервера работающиго на TheRyuzaki.Network</param> /// <param name="port">Порт до сервера работающиго на TheRyuzaki.Network</param> public Client(string ip, int port) { Cl["connect_status"] = false; Cl["client_ip"] = ip; Cl["client_port"] = port; } public void ConnectToServer() { Cl["client_thread"] = new Thread(delegate () { if (!(bool)Cl["connect_status"]) try { Cl["client_tcp"] = new TcpClient((string)Cl["client_ip"], (int)Cl["client_port"]); Cl["client_ns"] = (Cl["client_tcp"] as TcpClient).GetStream(); Cl["client_sr"] = new StreamReader((Cl["client_ns"] as NetworkStream)); Cl["client_sw"] = new StreamWriter((Cl["client_ns"] as NetworkStream)); Cl["connect_status"] = true; } catch { Cl["connect_status"] = false; } if (ConnectToServer_Completed != null) ConnectToServer_Completed(); Reading(); }); (Cl["client_thread"] as Thread).Start(); } /// <summary> /// Функция потокового прослушивания запросов от сервера /// </summary> private void Reading() { if ((bool)Cl["connect_status"]) try { while(true) { var request = (Cl["client_sr"] as StreamReader).ReadLine(); if (request.Length == 0) break; var ex = request.Split(';'); switch (ex[0]) { case "version": WriteForServer("version;" + build); break; default: if (ReadLineToServer != null) ReadLineToServer(request); break; } } Disconnect(); } catch { if ((Thread)Cl["client_thread"] != null) Disconnect(); } } /// <summary> /// Функция отправки запроса на сервер /// </summary> /// <param name="request">Запрос</param> /// <param name="WriteAllClients">Просто отправить всем клиентам</param> public void WriteForServer(string request, bool WriteAllClients = false) { if (!(bool)Cl["connect_status"]) return; if (WriteAllClients) request = "WriteAllClients;" + request; (Cl["client_sw"] as StreamWriter).WriteLine(request); (Cl["client_sw"] as StreamWriter).Flush(); } /// <summary> /// Функция разрыва соеденения с сервером /// </summary> public void Disconnect() { Cl["client_thread"] = null; try { (Cl["client_sr"] as StreamReader).Close(); } catch { } try { (Cl["client_sw"] as StreamWriter).Close(); } catch { } try { (Cl["client_ns"] as NetworkStream).Close(); } catch { } try { (Cl["client_tcp"] as TcpClient).Close(); } catch { } Cl["connect_status"] = false; if (DisconnectServer_Completed != null) DisconnectServer_Completed(); } } }
Server.cs
using System; using System.Collections.Generic; using System.Collections.Concurrent; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.IO; using System.Threading; namespace TheRyuzaki.Network { public class Server { private int build = 1; public Dictionary<string, object> Config = new Dictionary<string, object>(); public Dictionary<string, object> Srv = new Dictionary<string, object>(); #region Ссылки на функции CallBack /// <summary> /// Ссылка на функцию которая вызывается при успешном запуске сервера /// </summary> public Action ServerStarted = null; /// <summary> /// Ссылка на функцию которая вызывается при остановке сервера /// </summary> public Action ServerStoped = null; /// <summary> /// Ссылка на функцию которая вызывается при подключении нового клиента /// </summary> public Action<int> ClientConnected = null; /// <summary> /// Ссылка на функцию которая вызывается при отключении клиента от сервера /// </summary> public Action<int, Dictionary<string, object>> ClientDisconnected = null; /// <summary> /// Ссылка на функцию которая вызывается при получении сообщения от клиента /// </summary> public Action<int, string> ClientSendedMessage = null; #endregion /// <summary> /// Класс по работе Сервер-Клиент по сердствам TheRyuzaki.Network /// </summary> /// <param name="IP">IP адрес прослушки в формате IPAddress</param> /// <param name="Port">Порт прослушиваемый</param> public Server(IPAddress IP, int Port) { Config["server_ip"] = IP; Config["server_port"] = Port; Config["last_session"] = 0; Srv["server_thread"] = null; Srv["Server"] = new Dictionary<string, object>(); Srv["Users"] = new Dictionary<int, object>(); (Srv["Server"] as Dictionary<string, object>)["Listener"] = new TcpListener(IP, Port); } /// <summary> /// Функция запуска сервера /// </summary> public void StartServer() { if ((Srv["server_thread"] as Thread) != null) return; ((Srv["Server"] as Dictionary<string, object>)["Listener"] as TcpListener).Start(); Srv["server_thread"] = new Thread(delegate () { if (ServerStarted != null) ServerStarted(); while (true) { Socket Soc = null; try { Soc = ((Srv["Server"] as Dictionary<string, object>)["Listener"] as TcpListener).AcceptSocket(); } catch { break; } if (Soc.Connected) { Config["last_session"] = (int)Config["last_session"] + 1; var id_session = (int)Config["last_session"]; (Srv["Users"] as Dictionary<int, object>)[id_session] = new Dictionary<string, object>(); ((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["Thread"] = new Thread(delegate () { try { ((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["Soc"] = Soc; ((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["NS"] = new NetworkStream(Soc); ((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["SR"] = new StreamReader((((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["NS"] as NetworkStream)); ((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["SW"] = new StreamWriter((((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["NS"] as NetworkStream)); if (ClientConnected != null) ClientConnected(id_session); while (true) { var request = (((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["SR"] as StreamReader).ReadLine(); if (request.Length == 0) break; request = "WriteAllClients;" + request; var ex = request.Split(';'); switch (ex[0]) { case "version": if (build.ToString() != ex[1]) CloseSession(id_session); break; case "WriteAllClients": request = request.Replace("WriteAllClients;", ""); (new Thread(delegate () { foreach (var r in GetUsers()) if ((Srv["Users"] as Dictionary<int, object>).ContainsKey(r.Key)) SendMessage(request, r.Key); })).Start(); break; default: if (ClientSendedMessage != null) ClientSendedMessage(id_session, request); break; } } CloseSession(id_session); } catch { CloseSession(id_session); } }); (((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["Thread"] as Thread).Start(); } } }); (Srv["server_thread"] as Thread).Start(); } /// <summary> /// Функция остановки сервера /// </summary> public void StopServer() { if ((Srv["server_thread"] as Thread) == null) return; ((Srv["Server"] as Dictionary<string, object>)["Listener"] as TcpListener).Stop(); foreach(var r in GetUsers()) if ((Srv["Users"] as Dictionary<int, object>).ContainsKey(r.Key)) CloseSession(r.Key); (Srv["server_thread"] as Thread).Abort(); Srv["server_thread"] = null; if (ServerStoped != null) ServerStoped(); } /// <summary> /// Функция завершения сеанса сессии. /// Возвращает ответ: /// 0 = Закрыт успешно. /// 1 = Такой сессии не существует. /// 2 = Возникла ошибка при закрытии сесии. /// </summary> public int CloseSession(int id, bool NotRemove = false) { int i = 0; if ((Srv["Users"] as Dictionary<int, object>).ContainsKey(id)) try { try { (((Srv["Users"] as Dictionary<int, object>)[id] as Dictionary<string, object>)["Soc"] as Socket).Close(); } catch { } if (ClientDisconnected != null) ClientDisconnected(id, ((Srv["Users"] as Dictionary<int, object>)[id] as Dictionary<string, object>)); Thread tmp = (((Srv["Users"] as Dictionary<int, object>)[id] as Dictionary<string, object>)["Thread"] as Thread); if (!NotRemove) (Srv["Users"] as Dictionary<int, object>).Remove(id); tmp.Abort(); } catch { i = 2; // Записываем про чтоизошла ошибка } else i = 1; return i; } /// <summary> /// Функция отправки сообщения на клиент /// </summary> /// <param name="message">Само сообщение</param> /// <param name="id_session">ID сессии</param> public void SendMessage(string message, int id_session) { (((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["SW"] as StreamWriter).WriteLine(message); (((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["SW"] as StreamWriter).Flush(); } /// <summary> /// Функция получения списка ID сессий активных пользователей. Желательно проверять при работе на достоверность if ((Srv["Users"] as Dictionary<int, object>).ContainsKey(r.Key)) /// </summary> /// <returns>Dictionary<int, bool> - массив содержащий ID в ключе</returns> public Dictionary<int, bool> GetUsers() { var k =(Srv["Users"] as Dictionary<int, object>).Keys; Dictionary<int, bool> keys = new Dictionary<int, bool>(); foreach(var r in k) keys.Add(r, true); return keys; } } }
Решение задачи: «TheRyuzaki.Network v0.001 PreAlpha - Критика и оптимизация»
textual
Листинг программы
public void SendMessage(string message, int id_session) { (((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["SW"] as StreamWriter).WriteLine(message); (((Srv["Users"] as Dictionary<int, object>)[id_session] as Dictionary<string, object>)["SW"] as StreamWriter).Flush(); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д