Службы. Логика методов 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();
}