Службы. Логика методов OnStart & OnStop - C#

Узнай цену своей работы

Формулировка задачи:

Добрый вечер. По заданию нужно созданный сервер засунуть в службу. Собственно тут и появляется вопрос как это реализовать, код сервера:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.IO;
using System.Diagnostics;
 
namespace FarServer
{
    /// <summary>
    /// Вспомогательный класс
    /// </summary>
    public class StateObject
    {
        /// <summary>
        /// Текущее подключение.
        /// </summary>
        public Socket workSocket = null;
        /// <summary>
        /// Размер буфера.
        /// </summary>
        public const int BufferSize = 1024;
        /// <summary>
        /// Буфер для отправки и получения данных.
        /// </summary>
        public byte[] buffer = new byte[BufferSize];
    }
    /// <summary>
    /// Реализует асинхронный сервер.
    /// </summary>
    public class AsynchronousSocketListener
    {
        /// <summary>
        /// Класс события для поддержки синхронизации.
        /// </summary>
        public static ManualResetEvent allDone = new ManualResetEvent(false);
        /// <summary>
        /// 
        /// </summary>
        private static Socket listener;
        /// <summary>
        /// 
        /// </summary>
        private static bool IsListening;
        /// <summary>
        /// Запуск сервера.
        /// </summary>
        public static void StartListening()
        {
            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); //определяем имя компьютера.
            IPAddress ipAddress = ipHostInfo.AddressList[0]; // С помощью имени определяем IP компьютера.
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); //Создаем конечную точку.
 
            // Создаем экземпляр класса Сокет.
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                listener.Bind(localEndPoint);//Связываем Клиент и Сервер.
                listener.Listen(10);//Начинаем прослушку.
                Console.WriteLine("Ожидание подключений к " + localEndPoint);
                IsListening = true;
                while (IsListening)
                {
                    allDone.Reset();//останавливаем все потоки для подключения нового клиента.
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);  // Согласие на подключение.
                    allDone.WaitOne();  //Ожидание завершение работы другими потоками.
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
        /// <summary>
        /// Закрытие сервера.
        /// </summary>
        public static void FinishListening()
        {
            listener.Close();
            IsListening = false;
        }
        /// <summary>
        /// Принятие подключения.
        /// </summary>
        /// <param name="ar"></param>
        public static void AcceptCallback(IAsyncResult ar)
        {
            allDone.Set();//Возобновляем все потоки после установки соединения.
            if (IsListening == false) return;
            Socket listener = (Socket)ar.AsyncState;// Сокет для поучение запросов.
            Socket handler = listener.EndAccept(ar); //Новый сокет.
            StateObject state = new StateObject();
            state.workSocket = handler;//Делаем текущее подключение рабочим сокетом.
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);//Настраиваем прием данных от клиента.
            Console.WriteLine("Клиент " + handler.RemoteEndPoint + " подключился.");
        }
        /// <summary>
        /// Метод получения данных.
        /// </summary>
        /// <param name="ar"></param>
        public static void ReadCallback(IAsyncResult ar)
        {
            //переменная под полученные данные.
            String content = String.Empty;
            //Создаем рабочий сокет клиента который отсылает на сервер данные.
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;//сокет клиента с которым в данный момент идет взаимодействие.
            try
            {
                int bytesRead = handler.EndReceive(ar);//Количество полученных байт информации.
                if (bytesRead > 0)//Если есть информация
                {
                    if ((Encoding.ASCII.GetString(state.buffer, 0, 2)) == @"&>")// есть ли начальные символы.
                    {
                        for (int i = 2; i <= bytesRead; i++)
                        {
                            byte[] cpl = new byte[2] { state.buffer[i], state.buffer[i + 1] };//массив байт под объект CPL.
                            var k = new BitArray(cpl);//Переводим cpl в массив битов.
                            if (k[0] == false & cpl[0] != 0)//CPL это длина параметра если 1 бит равен нулю.
                            {   //смещаем все биты на 1 разряд влево.
                                for (int l = 0; l < k.Length - 1; l++)
                                {
                                    k[l] = k[l + 1];
                                }
                                k[k.Length - 1] = false; //послдений бит становится равен 0.
                                k.CopyTo(cpl, 0);//конвертируем массив бит обратно в байты.
                                short _length = BitConverter.ToInt16(cpl, 0);//Узнаем из CPL длину параметра.
                                content += (Encoding.GetEncoding(1251).GetString(state.buffer, i + 2, _length) + " ");
                                i += _length + 1;
                            }
                            else //CPL команада
                            {
                                if (k[0] == true)//CPL это команда 1 бит равен еденице.
                                {  //Преобразуем номер команды в слово.
                                    FarServer.DictionaryCommands dict = new FarServer.DictionaryCommands();
                                    if (dict.comands.ContainsKey((byte)cpl[1]))
                                    {
                                        if ((byte)cpl[1] != 18)
                                        {
                                            content += "/" + dict.comands[(byte)cpl[1]];
                                        }
                                        else FinishListening();
 
                                    }
                                    i++;
                                }
                            }
                        }
                        if (content.IndexOf("<&") > -1)//Проверка на наличие конца запроса.
                        {
                            try
                            {
                                if (IsListening)
                                {
                                    content = content.Remove(content.Length - 3);//убираем символы окончания программы из запроса.
                                    //Вызываем тестовую программу с параметрами.
                                    Process process = new Process();
                                    process.StartInfo.FileName = @"FileManager\test\bin\Debug\test.exe";
                                    process.StartInfo.Arguments = content;
                                    process.StartInfo.UseShellExecute = false;
                                    process.StartInfo.RedirectStandardOutput = true;
                                    process.Start();
                                    List<string> output = new List<string>();
                                    StreamReader reader = process.StandardOutput;
                                    output.Add(reader.ReadToEnd());
                                    //Полученyый результат отправляем клиенту.
                                    foreach (string st in output)
                                        Send(handler, st);
                                }
                                else Send(handler, "Cервер отключился.");
                            }
                            catch (Exception exc)
                            {
                                Send(handler, exc.ToString());
                            };
                        }
                    }
                }
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
            }
            catch (Exception exc)
            {
                Console.WriteLine("Клиент " + handler.RemoteEndPoint + " отключился.");
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
                allDone.Set();
            }
 
        }
        /// <summary>
        /// Передает данные клиенту
        /// </summary>
        /// <param name="handler">сокет клиента которому передаются данные.</param>
        /// <param name="data">Передаваемые данные.</param>
        private static void Send(Socket handler, String data)
        {
            // Конвертируем строку с ответом в массив байтов.
            byte[] byteData = Encoding.GetEncoding(1251).GetBytes(data);
            // Начинаем отправку ответа клиенту.
            handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
        }
        /// <summary>
        /// первоначально закрывал сокет клиента которому отправили данные.
        /// </summary>
        /// <param name="ar"></param>
        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket handler = (Socket)ar.AsyncState;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public static int Main(String[] args)
        {
            StartListening();
            return 0;
        }
    }
}
ниже способ как я пытаюсь засунуть сервер в службу(насколько я понял способ неправильный):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using Far = FarServer.AsynchronousSocketListener;
 
namespace WindowsService1
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
        }
 
        protected override void OnStart(string[] args)
        {
            Far.StartListening();
        }
 
        protected override void OnStop()
        {
            Far.FinishListening();
        }
    }
}
Прошу помощи у сведущих людей, поскольку сам не понимаю в чем проблема. Единственное мое предположение что это из-за бесконечного цикла который нарушает правило 30 секунд для OnStart.

Решение задачи: «Службы. Логика методов OnStart & OnStop»

textual
Листинг программы
protected override void OnStart(string[] args)
        {
            Far.StartListening();
        }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 4 из 5
Похожие ответы