Службы. Логика методов OnStart & OnStop - C#
Формулировка задачи:
Добрый вечер. По заданию нужно созданный сервер засунуть в службу. Собственно тут и появляется вопрос как это реализовать, код сервера:
ниже способ как я пытаюсь засунуть сервер в службу(насколько я понял способ неправильный):
Прошу помощи у сведущих людей, поскольку сам не понимаю в чем проблема. Единственное мое предположение что это из-за бесконечного цикла который нарушает правило 30 секунд для OnStart.
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(); } } }
Решение задачи: «Службы. Логика методов OnStart & OnStop»
textual
Листинг программы
protected override void OnStart(string[] args) { Far.StartListening(); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д