Класс TcpListener

150

Обычно приложение стороны сервера начинает работу, связываясь с локальной конечной точкой и ожидает входящие запросы от клиентов. Как только клиент достиг порта, приложение активизируется, принимает запрос и создает канал, предназначенный для взаимодействия с этим клиентом. На основном потоке приложение продолжает ожидать другие входящие запросы от клиентов.

Класс TcpListener делает именно это — он слушает запросы клиентов, принимает запрос и создает новый экземпляр класса Socket или класса TcpClient, которые можно использовать для взаимодействия с клиентом. Как и TcpClient, класс TcpListener также инкапсулирует закрытый объект Socket - m_ServerSocket, доступный только для производных классов.

В следующей таблице показаны важные свойства и методы класса TcpListener:

Свойства и методы класса 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();
Пройди тесты
Лучший чат для C# программистов