none
Сервис загружает процессор. RRS feed

  • Вопрос

  • Эммм... Незнаю даже как подступится к этому...

    Есть программа, написанная мной, выполняет роль сервера:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    using System.Timers;

    namespace Server
    {
        public struct ClientInfo
        {
            public string ClientName; //Имя компьютера
            public string ClientIP; //IP компьютера
            public string ClientPort; //Port компьютера
            public Thread ClientThread; //Поток соединения
            public Thread ActionThread; //Поток действия
            public Connection ClientConnection; //Экземпляр класса
            public int ClientNumber; //Порядковый номер
            public BinaryReader StringsReader; //Поток чтения данных от клента
            public BinaryWriter StringsWriter; //Поток передачи данных клиенту
            public bool IsOnline; //Результат проверки доступен ли клиент
        }

        public struct ServerInfo
        {
            public string ServerName; //Имя компьютера
            public string ServerIP; //IP компьютера
            public int ServerPort; //Port компьютера
            public Thread ServerThread; //Поток соединения
            public Thread ActionThread; //Поток действия
            public TcpClient ServerConnection; //Экземпляр класса
            public int ServerNumber; //Порядковый номер
            public BinaryReader StringsReader; //Поток чтения данных от клента
            public BinaryWriter StringsWriter; //Поток передачи данных клиенту
            public bool IsConnected; //Результат проверки включен ли сервер
        }
        public class Server
        {
            public static System.Timers.Timer ConnectionCheck;
            public static System.Timers.Timer ServerConnectionCheck;
            public static ActionDealer ADeal = new ActionDealer();
            public static ClientInfo[] ClInfo = new ClientInfo[100];
            public static ServerInfo SInfo = new ServerInfo();
            public static int ClientCounter = 0;
            static void Main(string[] args)
            {
                Thread ListenerServer = new Thread(ServerUp);
                ListenerServer.Start();
                Thread ListenerConsole = new Thread(ReadingConcole);
                ListenerConsole.Start();
                ConnectionCheck = new System.Timers.Timer();
                ConnectionCheck.Elapsed += new ElapsedEventHandler(ConnectionCheck_Tick);
                ConnectionCheck.Interval = 1000;
                ConnectionCheck.Enabled = true;
                //reg();
            }
            private static void ServerUp()
            {
                // Получение имени компьютера.
                ADeal.LogWrite("JusteG's ServeR ver. 1.0.0.156 starting", ConsoleColor.DarkCyan);
                int Port = 1116;
                string[] GetHostName;
                IPHostEntry GetHostEntry;
                TcpListener Listener = new TcpListener(IPAddress.Any, Port); //и на нем у нас висит сервер
                Listener.Start(); //серер запущен
                ADeal.LogWrite("Server started on " + Port.ToString(), ConsoleColor.DarkCyan);

                while (true)
                {
                    TcpClient ConectedClient = Listener.AcceptTcpClient();
                    if (ClientCounter == 99) ClientCounter = 0;
                    ClientCounter += 1;
                    ClInfo[ClientCounter].ClientNumber = ClientCounter;
                    ClInfo[ClientCounter].ClientConnection = new Connection();
                    ClInfo[ClientCounter].ClientConnection.ClInfo = ClInfo;
                    ClInfo[ClientCounter].ClientConnection.IDClient = ClientCounter;
                    ClInfo[ClientCounter].ClientPort = ConectedClient.Client.RemoteEndPoint.ToString();
                    GetHostName = ClInfo[ClientCounter].ClientPort.Split(':');
                    ClInfo[ClientCounter].ClientIP = GetHostName[0];
                    ClInfo[ClientCounter].ClientPort = GetHostName[1];
                    GetHostEntry = Dns.GetHostByAddress(GetHostName[0]);
                    ClInfo[ClientCounter].ClientName = GetHostEntry.HostName;
                    ADeal.LogWrite("\n____________________\nNew client connected", ConsoleColor.DarkGreen);
                    ClInfo[ClientCounter].ClientConnection.ConectedClient = ConectedClient;
                    Thread ClientThread = new Thread(new ThreadStart(ClInfo[ClientCounter].ClientConnection.Work));
                    ClInfo[ClientCounter].ClientThread = ClientThread;
                    ClientThread.IsBackground = false;
                    ClientThread.Start();
                    bool Leaving = ClInfo[ClientCounter].ClientThread.IsAlive;
                }
            }

            private static void ReadingConcole()
            {
                string WConsole;
                while (true)
                {
                    WConsole = Console.ReadLine();
                    for (int i = 1; i < 100; i++)
                    {
                        try
                        {
                            ClInfo[i].StringsWriter.Write(WConsole);
                        }
                        catch { }
                    }
                }
            }

            private static void ConnectionCheck_Tick(Object sender, ElapsedEventArgs e)
            {
                for (int i = 1; i < 100; i++)
                {
                    try
                    {
                        if (ClInfo[i].ClientConnection.ConectedClient.Connected)
                        {
                            if (ClInfo[i].IsOnline == false)
                            {
                                ADeal.LogWrite("Client " + ClInfo[i].ClientNumber + " " + ClInfo[i].ClientName + " OnLine", ConsoleColor.DarkGreen);
                                ClInfo[i].IsOnline = true;
                            }
                        }
                        else
                        {
                            if (ClInfo[i].IsOnline == true)
                            {
                                ADeal.LogWrite("Client " + ClInfo[i].ClientNumber + " " + ClInfo[i].ClientName + " OffLine", ConsoleColor.DarkRed);
                                ClInfo[i].ClientThread.Abort();
                                ClInfo[i].IsOnline = false;
                            }
                        }
                    }
                    catch { }
                }
            }

            private static void ServerConnectionCheck_Tick(Object sender, ElapsedEventArgs e)
            {
                try
                {
                    if (!SInfo.ServerConnection.Connected)
                    {
                        if (SInfo.IsConnected)
                        {
                            SInfo.ServerConnection.Close();
                            SInfo.ServerThread.Abort();
                            ADeal.LogWrite("Соединение с удаленным сервером закрыто", ConsoleColor.DarkRed);
                            SInfo.IsConnected = false;
                        }
                    }
                }
                catch { }
            }

            private static void reg()
            {
                ServerConnectionCheck = new System.Timers.Timer();
                ServerConnectionCheck.Elapsed += new ElapsedEventHandler(ServerConnectionCheck_Tick);
                ServerConnectionCheck.Interval = 1000;
                ServerConnectionCheck.Enabled = true;
                string ResivedString;
                SInfo.ServerIP = "192.168.0.6";
                SInfo.ServerPort = 1116;
                //создадим сокетное подключение для общения с сервером
                SInfo.ServerConnection = new TcpClient(SInfo.ServerIP, SInfo.ServerPort); //IP адрес сервера и порт на котором он висит
                NetworkStream NWS = SInfo.ServerConnection.GetStream();
                SInfo.StringsReader = new BinaryReader(NWS); //поток для принятия данных
                SInfo.StringsWriter = new BinaryWriter(NWS); //поток для отправки данных
                SInfo.ServerThread = new Thread(ReadingMessage);
                SInfo.ServerThread.Start();
                SInfo.IsConnected = true;
                try
                {
                    while (true)
                    {
                        ResivedString = Console.ReadLine();
                        SInfo.StringsWriter.Write(ResivedString);
                    }
                }
                catch { }
            }
            private static void ReadingMessage()
            {
                string ResivedString;
                try
                {
                    while (true)
                    {
                        ResivedString = SInfo.StringsReader.ReadString();
                        Console.WriteLine("-> " + ResivedString);
                    }
                }
                catch { }
            }
        }
        public class Connection
        {
            public ClientInfo[] ClInfo;
            public int IDClient;
            public static ActionDealer ADeal = new ActionDealer();
            public TcpClient ConectedClient;
            string ResivedString;
            public void Work()
            {
                NetworkStream NWS = ConectedClient.GetStream();
                ClInfo[IDClient].StringsReader = new BinaryReader(NWS); //принятие
                ClInfo[IDClient].StringsWriter = new BinaryWriter(NWS); //отправка
                WellcomeClient();
                Thread Reading = new Thread(ReadingMessage);
                Reading.Start();
            }

            private void ReadingMessage()
            {
                try
                {
                    while (true)
                    {
                        ResivedString = ClInfo[IDClient].StringsReader.ReadString();
                        DoReact(ResivedString);
                    }
                }
                catch { }
            }

            private void WellcomeClient()
            {
                ADeal.LogWrite("Client Params:\n", ConsoleColor.DarkGreen);
                ADeal.LogWrite("Name:\t" + ClInfo[IDClient].ClientName, ConsoleColor.DarkGreen);
                ADeal.LogWrite("IP:\t" + ClInfo[IDClient].ClientIP, ConsoleColor.DarkGreen);
                ADeal.LogWrite("Port:\t" + ClInfo[IDClient].ClientPort, ConsoleColor.DarkGreen);
                ADeal.LogWrite("ID:\t" + ClInfo[IDClient].ClientNumber, ConsoleColor.DarkGreen);
                ClInfo[IDClient].StringsWriter.Write("You are welcome " + ClInfo[IDClient].ClientName);
                ClInfo[IDClient].StringsWriter.Write("You IP is " + ClInfo[IDClient].ClientIP);
                ClInfo[IDClient].StringsWriter.Write("You Local Port is " + ClInfo[IDClient].ClientPort);
                ClInfo[IDClient].StringsWriter.Write("You ID is " + ClInfo[IDClient].ClientNumber);
            }

            private void DoReact(string Action)
            {
                ActionDealer ActionD = new ActionDealer();
                ActionD.ClInfo = ClInfo;
                ActionD.IDClient = IDClient;
                ActionD.DoReact(Action, IDClient);
            }
        }
        public class ActionDealer
        {
            public ClientInfo[] ClInfo;
            public int IDClient;
            public void DoReact(string Action, int IDClient)
            {
                LogWrite("\nКлиент " + IDClient + " запросил действие \"" + Action + "\"", ConsoleColor.DarkYellow);
                LogWrite("Выполняю...", ConsoleColor.DarkGreen);
                switch (Action)
                {
                    #region Who Online
                    case "Who Online":
                        for (int i = 1; i < 100; i++)
                        {
                            try
                            {
                                if (ClInfo[i].IsOnline)
                                    ClInfo[IDClient].StringsWriter.Write(ClInfo[i].ClientNumber + " " + ClInfo[i].ClientName);
                            }
                            catch { }
                        }
                        break;
                    #endregion
                    #region Date
                    case "Date":
                        ClInfo[IDClient].StringsWriter.Write(DateTime.Now.ToLongDateString());
                        break;
                    #endregion
                    #region Time
                    case "Time":
                        ClInfo[IDClient].StringsWriter.Write(DateTime.Now.ToLongTimeString());
                        break;
                    #endregion
                    #region FileTransfer
                    case "Ftransfer":
                        ClInfo[IDClient].StringsWriter.Write("Name");
                        string FileName = ClInfo[IDClient].StringsReader.ReadString();
                        LogWrite("Имя файла определенно - " + FileName, ConsoleColor.DarkYellow);
                        ClInfo[IDClient].StringsWriter.Write("Folder");
                        string FolderName = ClInfo[IDClient].StringsReader.ReadString();
                        LogWrite("Путь к папке определен - " + FolderName, ConsoleColor.DarkYellow);
                        FileStream Writing = File.OpenWrite(FolderName + @"\" + FileName);
                        byte[] Buffer = new byte[128];
                        byte[] BytesInArray = BitConverter.GetBytes(-1);
                        BytesInArray.CopyTo(Buffer, 0);
                        LogWrite("Начинаю прием файла " + FileName, ConsoleColor.DarkYellow);
                        while (BitConverter.ToInt32(Buffer, 0) != 0)
                        {
                            Buffer = ClInfo[IDClient].StringsReader.ReadBytes(128);
                            Writing.Write(Buffer, 4, BitConverter.ToInt32(Buffer, 0));
                        }
                        LogWrite("Файл " + FileName + " успешно получен!", ConsoleColor.DarkGreen);
                        Writing.Close();
                        LogWrite("Файл " + FileName + " сохранен в папке " + FolderName + "!", ConsoleColor.DarkGreen);
                        break;
                    #endregion
                    #region ToCopy
                    #endregion
                    #region Close
                    case "Close":
                        ClInfo[IDClient].ClientConnection.ConectedClient.Close();
                        ClInfo[IDClient].ClientThread.Abort();
                        break;
                    #endregion
                    #region Help
                    case "Help":
                        ClInfo[IDClient].StringsWriter.Write("Commands:\nWho Online\nDate\nTime\nClose");
                        break;
                    #endregion
                }
                LogWrite("Отправляю ответ...", ConsoleColor.DarkGreen);
                ClInfo[IDClient].StringsWriter.Write("Запрошенное действие \"" + Action + "\" успешно обработанно.");
                Console.ForegroundColor = ConsoleColor.White;
            }
            public void LogWrite(string Text, ConsoleColor CColor = ConsoleColor.White)
            {
                Console.ForegroundColor = CColor;
                Console.WriteLine(Text);
                Console.ForegroundColor = ConsoleColor.White;
            }
        }
    }

    Программа вполне адекватно и устойчиво работает, но стоит сделать ее сервисом (скопировать код в приложение - сервис и из метода майн перенести все в метод онстарт) она начинает есть ресурсы, грузит процессор на 10-15%, в консольном виде она такого поведения не проявляет... Что характерно, несмотря на загруженность процессора, она продолжает корректно работать, как к ней подступится? Оптимизация? Что-то неправильно сделал? Помогите пожалуйста!

    • Перемещено Tagore Bandlamudi 3 октября 2010 г. 0:35 MSDN Forums consolidation (От:Форум по .NET Framework)

Ответы

  • похоже в главном цикле стоит как минимум добавить задержку Thread.Sleep(10);

    на производительность и 100 мс не повлияет, а вот процессор разгрузит серьезно

    • Помечено в качестве ответа JusteG 18 мая 2010 г. 4:12

Все ответы

  • похоже в главном цикле стоит как минимум добавить задержку Thread.Sleep(10);

    на производительность и 100 мс не повлияет, а вот процессор разгрузит серьезно

    • Помечено в качестве ответа JusteG 18 мая 2010 г. 4:12
  • Проблема была действительно в этом.

    Код осекался в методе "ReadingConcole", где поидее должен циклично читать консоль которая не открыта... Решил проблему закоментировав создание потока чтения консоли.

    Спасибо вам!