Создание Internet-приложений в среде Delphi. Работа с событиями сокетов

   
На этом шаге мы рассмотрим принципы работы с событиями сокетов.

   
События, возникающие при работе с сокетами, можно условно разделить на следующие группы:

  • события закрытия и открытия соединения,
  • события чтения и записи, и
  • события сообщающие об ошибке.

   
Когда клиентский сокет открывает соединение, при этом происходит целая цепь событий.

  • В самом начале вызывается событие OnLookup. В нем вы уже не сможете поменять значения свойств
    Host, Address, Port или Service. Но вы можете изменить свойства сокета Windows, обратившись
    к этому объекту через свойство Socket. Например, вы можете изменить значение порта на стороне клиента.
  • Свойства сокета Windows получают значения и происходит инициализация сокета.
  • Когда обнаруживается серверный сокет, происходит событие ОnСоnnecting. Хотя соединение еще не установлено,
    в обработчике этого события вы уже можете узнать параметры серверного сокета.
  • Серверный сокет открывает соединение; в ответ на это клиентский сокет завершает работу по установлению соединения.
  • И, напоследок, после установления соединения, наступает событие OnConnect. Если вашему приложению нужно начинать чтение или
    передачу данных сразу после установления соединения, вы можете сделать это из обработчика данного события.

   
Серверный сокет выполняет сразу две задачи: он поддерживает слушающее соединение и соединения с клиентскими сокетами.

   
Как только слушающий сокет получает запрос от клиента на соединение, происходит событие OnListen. Здесь, с помощью свойства Socket,
вы можете получить сведения относительно клиентского сокета и как-то вмешаться в процесс: например, если вы контролируете процесс подключения
клиентов, то здесь вы можете отказать в соединении "нежелательным" IP-адресам.

   
При установлении соединения с клиентом процесс проходит следующие фазы.

  • Генерируется событие OnGetSocket, когда серверному сокету требуется создать новый экземпляр TServerClientWinSocket. Если вы хотите
    создать свой вариант потомка TServerClientWinSocket, то вы можете сделать это в данном обработчике и вернуть его через параметр ClientSocket.
  • Затем происходит событие OnAccept. Обработчику этого события через параметр Socket передается созданный на предыдущем этапе
    экземпляр наследника объекта TServerClientWinSocket. Вы можете получить информацию о создаваемом соединении.
  • Следующие два события генерируются, если серверный сокет является блокирующим (свойство ServerType имеет значение
    stThreadBlocking). Первое событие называется OnGetThread. Вы можете использовать обработчик этого события для создания собственного потока,
    потомка TServerClientThread.
  • Второе из рассматриваемых событий, это событие OnThreadStart. Вы можете использовать это событие для инициализации потока, выполнения каких-либо
    вызовов API-функций сокетов Windows, пока поток не приступил к чтению или записи данных по установленному соединению.
  • После того, как клиент закончит процесс установления связи, вызывается событие OnClientConnect. Если серверный сокет не блокирующий, то вы сразу
    можете приступить к обмену данными.

   
Обмен данными - это очевидно основная задача установленного соединения сокетов. Эта задача может выполняться двумя способами, в зависимости
от того, какой тип сокетов мы используем: блокирующие или не блопирующие. Если сокет не блокирующий (у клиентского сокета свойство ClientType имеет значение
ctNonBlocking, а у серверного сокета свойству ServerType присвоено значение stNonBlocking), то операции чтения/записи происходят асинхронно
и не блокируют выполнение программного кода. Если сокеты используют режим блокировки (у клиентского сокета свойство ClientType имеет значение ctBlocking,
а у серверного сокета свойству ServerType присвоено значение stThreadBlocking), операции чтения и записи начинаются только после инициализации. В таком
режиме работы при создании нового соединения серверный сокет выделяет для него свой поток, чтобы процесс блокировки не мешал работе остальных соединений.
В зависимости от выполняемой задачи бывает, что приходится выделять для процессов чтения и записи на клиентской стороне соединения отдельный поток. Но это уже вам решать - делать это или нет.

   
В случае неблокирующих сокетов, когда сокет получает запрос на чтение или запись, вызываются события OnRead и OnWrite у клиентского сокета и события
OnClientRead и OnClientWrite у серверного сокета. В обработчиках этих событий вы должны разместить соответствующий код, выполняющий эти задачи.
Для чтения данных нужно применять методы ReceiveBuf и ReceiveText. Для первого метода сначала нужно узнать размер присылаемого другим сокетом буфера.
Сделать это можно при помощи метода ReceiveLength. Чтобы записать данные в соединение сокетов можно использовать один из трех методов: SendBuf,
SendStream или SendText. Если применить метод SendStreamThenDrop, то после отправки данных сервер разорвет соединение.

   
Когда сокеты работают в режиме блокировки, то задача программиста - отслеживать, когда сокет на другом конце соединения готов принять или отправить данные, поскольку
блокирующие сокеты не обмениваются такой информацией друг с другом. Программист должен использовать для этой цели свойства и методы объекта TWinSocketStream.

   
На следующем шаге мы рассмотрим пример использования изученного материала.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий