Ватсон Карли
Шрифт:
Постепенно начнем создавать исходный код класса
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;
}
}
Помимо
Start
существуют другие методы для управления службой: Stop
, Suspend
и Resume
: public void Stop {
listener.Stop;
}
public void Suspend {
listenerThread.Suspend;
}