QuoteServer содержит реальную функциональность. Мы прочитаем файл цитат в кэш памяти и будем отвечать на запросы цитат с помощью сервера сокета.

QuoteСlient является клиентским приложением Windows Forms. Это приложение создает клиентский сокет для коммуникации с QuoteServer. Третья сборка является реальной службой. QuoteService запускает и останавливает QuoteServer, служба будет управлять сервером:

Прежде чем разработать служебную часть программы, создадим простой сервер сокета в дополнительной библиотеке классов C#, которая будет использоваться из процесса службы.

Библиотека классов, использующая сокеты

В системе Windows 2000 Server можно установить службы простого TCP/IP как компоненты Windows. Частью служб простого TCP/IP является сервер TCP/IP 'цитата дня' ('quote of the day', кратко называемая 'qotd'). Эта простая служба слушает порт 17 и отвечает на каждый запрос случайным сообщением из файла c:winntsystem32driversetcquotes. Здесь будет создан аналогичный сервер. Только этот сервер возвращает строку Unicode, в отличие от старого qotd, который возвращает код ASCII.

Постепенно начнем создавать исходный код класса QuoteServer в файле QuoteServer.cs:

using System;

using System.IO;

using System.Threading;

using System.Net.Sockets;

using System.Text;

using System.Collections.Specialized;

namespace Wrox.ProfessionalCSharp {

 /// <summary>

 /// Пример сервера сокета.

 /// </summary>

 public class QuoteServer {

  private TcpListener listener;

  private int port;

  private string filename;

  private StringCollection quotes;

  private Random random;

  private Thread listenerThread;

Конструктор QuoteServer() является перезагруженным, чтобы имя файла и порт можно было передать в вызове. Конструктор, где передается только имя файла, использует для сервера по умолчанию порт 7890. Конструктор по умолчанию определяет имя файла по умолчанию для цитат как quotes.txt:

  public QuoteServer() : this('quotes.txt') {}

  public QuoteServer(string filename) : this(filename, 7890) {}

  public QuoteServer(string filename, int port) {

   this.filename = filename;

   this.Port = port;

  }

ReadQuotes() является вспомогательным методом, который читает все цитаты из файла, который был определен в конструкторе. Все цитаты добавляются в StringCollection quotes. Кроме того создается экземпляр класса Random, который будет использоваться для возврата случайных цитат:

  protected void ReadQuotes() {

   quotes = new StringCollection();

   Stream stream = File.OpenRead(filename);

   StreamReader StreamReader = new StreamReader(stream);

   string quote;

   while ((quote = streamReader.ReadLine()) != null) {

    quotes.Add(quote);

   }

   streamReader.Close(); stream.Close();

   random = new Random();

  }

Другим вспомогательным методом является GetRandomQuoteOfTheDay(). Этот метод возвращает случайную цитату из цитат StringCollection quotes:

  protected string GetRandomQuoteOfTheDay() {

   int index = random.Next(0, quotes.Count); return quotes[index];

  }

В методе Start() весь файл, содержащий цитаты, в StringCollection quotes считывается с помощью вспомогательной функции ReadQuotes(). После этого запускается новый поток выполнения, который незамедлительно вызывает метод Listener(). Мы используем поток выполнения, так как метод Start() не может блокироваться и ждать клиента, он должен сразу же вернуть управление вызывающей стороне (SCM). SCM предположит, что запуск отказал, если метод не вернет своевременно управление вызывающей стороне.

  public void Start() {

   ReadQuotes();

   listenerThread = new Thread(new ThreadStart(this.Listener));

   listenerThread.Start();

  }

Функция потока выполнения Listener() создает экземпляр TCPListener. В методе AcceptSocket() ожидается соединение клиента. Как только клиент соединяется, AcceptSocket() возвращает управление с сокетом, связанным с клиентом. Метод GetRandomQuoteOfTheDay() вызывается для отправки возвращаемой случайной цитаты клиенту с помощью socket.Send():

  protected void Listener() {

   listener = new TcpListener(port);

   listener.Start();

   while (true); {

    Socket socket = listener.AcceptSocket();

    if (socket == null) {

     return;

    }

    string message = GetRandomQuoteOfTheDay();

    UnicodeEncoding encoder = new UnicodeEncoding();

    byte [] buffer = encoder.GetBytes(message);

    socket.Send(buffer, buffer.Length, 0);

    socket.Close();

   }

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату