Класс TcpListener
150C# и .NET --- Сетевое программирование --- Класс TcpListener
Обычно приложение стороны сервера начинает работу, связываясь с локальной конечной точкой и ожидает входящие запросы от клиентов. Как только клиент достиг порта, приложение активизируется, принимает запрос и создает канал, предназначенный для взаимодействия с этим клиентом. На основном потоке приложение продолжает ожидать другие входящие запросы от клиентов.
Класс TcpListener делает именно это — он слушает запросы клиентов, принимает запрос и создает новый экземпляр класса Socket или класса TcpClient, которые можно использовать для взаимодействия с клиентом. Как и TcpClient, класс TcpListener также инкапсулирует закрытый объект Socket - m_ServerSocket, доступный только для производных классов.
В следующей таблице показаны важные свойства и методы класса TcpListener:
Свойство или метод | Тип | Описание |
---|---|---|
LocalEndpoint | IPEndpoint | Это свойство возвращает объект IPEndpoint, который содержит информацию о локальном сетевом интерфейсе и номере порта, используемую для ожидания входящих запросов от клиентов. |
AcceptSocket() | Дает согласие на ожидающий запрос соединения и возвращает объект Socket, используемый для взаимодействия с клиентом. | |
AcceptTcpClient() | Дает согласие на ожидающий запрос соединения и возвращает объект TcpClient, используемый для взаимодействия с клиентом. | |
Pending() | Указывает, есть ли ожидающие запросы соединения. | |
Start() | Принуждает TcpListener начать слушать запросы соединения. | |
Stop() | Закрывает слушающий объект. | |
Active | bool | Указывает, слушает ли в настоящий момент TcpListener запросы соединения. |
Server | Socket | Возвращает базовый объект Socket, используемый объектом TcpListener, чтобы слушать запросы соединения. |
Существуют три перегруженных конструктора TcpListener:
public TcpListener(int port);
public TcpListener(IPEndPoint endPoint);
public TcpListener(IPAddress ipAddr, int port);
Первый конструктор просто указывает, какой порт используется, чтобы слушать запросы. В этом случае IP-адрес равен IPAddress.Any, т.е. сервер принимает действия клиентов на всех сетевых интерфейсах. Это значение эквивалентно IP-адресу 0.0.0.0. Второй конструктор принимает объект IPEndPoint, определяющий IP-адрес. Последний перегруженный конструктор принимает объект IPAddress и номер порта.
На следующем шаге после создания сокета начинаем слушать запросы клиентов. В классе TcpListener есть метод Start() выполняющий такую последовательность. Сначала он связывает сокет, используя IP-адрес и порт, переданные в параметрах конструктору TcpListener. Затем, вызвав метод Listen() базового объекта Socket, он начинает слушать запросы соединений от клиентов:
IPAddress ipAddr = IPAddress.Parse("127.0.0.1");
TcpListener listener = new TcpListener(ipAddr, 11000);
listener.Start();
Уже приступив к прослушиванию сокета, можно вызывать метод Pending(), чтобы проверять, нет ли ожидающих запросов соединения в очереди. Этот метод позволяет проверять наличие ожидающих клиентов до вызова метода Accept, который будет блокировать выполняющийся поток:
if (listener.Pending())
{
Console.WriteLine("Соединение добавлено в очередь");
}
Типичная серверная программа оперирует двумя сокетами: один используется классом TcpListener, а второй — для взаимодействия с отдельным клиентом. Чтобы дать согласие на любой запрос, ожидающий в настоящий момент в очереди, можно воспользоваться методом AcceptSocket() или более простым методом AcceptTcpClient(). Эти методы возвращают соответственно объекты Socket или TcpClient и дают согласие на запросы клиентов.
В зависимости от типа сокета, созданного при установлении соединения, реальный обмен данными между клиентом и сокетом сервера выполняется методами Send() и Receive() объекта Socket или с помощью чтения-записи объекта NetworkStream.
После завершения взаимодействия с клиентом нужно выполнить последний шаг — остановить слушающий сокет. Для этого вызывается метод Stop() объекта TcpListener:
listener.Stop();