Использование ServerSocket в Delphi 6

У экземпляра объекта ServerSocket есть следующие события:

Запуск экземпляра ServerSocket например ServerSocket1 может быть произведён следующим кодом:
ServerSocket1.Port:= 5505;
ServerSocket1.Open;

Обратите внимание указывается только Port, IP адрес по какой то причине не предусмотрен компонентом, поэтому сервер будет доступен на всех IP адресах имеющихся у ПК и на указанном порту. После выполнения указанных строчек и до подключения к серверу клиентов единственное событие которое произойдёт - OnListen.

Если теперь подключится какой либо клиент(например через telnet для чего нужно выполнить telnet затем o IP_адрес порт и нажать Enter) то на ServerSocket последовательно произойдут следующие события:

Попробуем обратиться на порт с браузера, я для этого использовал Internet Explorer 6 и Firefox 43.0.1 и это не смотря на то что эта статья 2020 года, дело в том что на момент написания я чтобы не разбираться с особенностями работы Delphi 6 в Windows 10 установил виртуальную машину с Windows XP образ которой доступен по ссылке. Я не утверждаю, что стоит разрабатывать на Delphi 6 необходимо именно в Windows XP, в моём случаи я посчитал что такой вариант сэкономит мне время.

Так вот, при обращении на порт с ServerSocket с браузера к указанным выше 4-м событиям которые выполняются при подключении к порту клиента добавляется ещё событие OnClientRead, поскольку после соединения браузер считая что соединился с Web-сервером передаёт заголовки содержащие в частности информацию о запрашиваемой странице. При этом есть особенность, которая я пока не знаю с чем именно связана: при подключении на порт с браузера событие OnClientWrite может выполняться после OnClientRead, но в любом случаи оба эты события выполняются после события OnAcept. То есть запустим программу на Delphi и выполним ServerSocket1.Open; в одном случаи при соединении с портом с браузера(не важно IE 6 или Firefox 43.0.1) первым может выполниться событие OnClientWrite а затем OnClientRead, а в дргом аналогичном случаи эти события могут произойти в обратной последовательности, поэтому учитывайте это при разработке софта.

Если же после подключения клиента через telnet с telnet попробовать отправить какое либо сообщение(по нажатию любой буквы она отправляется в telnet сразу), то в программе на Delphi мы увидим сработавшее событие OnClientRead, если же попробовать отправить сообщение из программы на Delphi такому клиенту каких либо событий в программе не отобразится, при этом в telnet мы увидим отправленное сообщение.

Для подавления некоторых ошибок в работе ServerSocket и использовал следующий код:
procedure TForm1.ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
Socket.Close;
ErrorCode:=0;
Memo1.Lines.Add('ClientError');
end;
В данном коде закрывается Socket на котором произошла ошибка, а так же переменной кода ошибки присваивается 0. Данный код вовсе не означает что не произойдёт ошибок в результате которых работа программы завершится, например такое завершение может произойти при попытке отключить не существующего клиента, например кодом ServerSocket1.Socket.Connections[2].Close; в этом случаи если клиента нет в массиве соединений с таким индексом выполнение программы завершится ошибкой.

Особенности организации Web-сервера на компоненте ServerSocket

Возможно Вы знаете, что после того как Web-сервер принимает от клиента информацию о запрашиваемой странице с прочими заголовками запроса, далее Web-сервер отдаёт клиенту информацию с заголовками ответа а так же тело HTML страницы, при это заголовки отделяются от тела страницы двойным отступом, который в Delphi может быть добавлен к переменной строки следующим образом: #13+#10+#13+#10 то есть Enter(#13) + возврат каретки(#10) и как видно эта комбинация повторяется дважды и идут они друг за другом. Заголовки в ответе отделяются одним переносом строки(то есть #13+#10).

Касаемо самих заголовков, в Интернете я встречал статьи где при организации Web-сервера на ServerSocket предлагается в частности передавать заголовок ответа - Length который содержит длину строки содержащей HTML контент(без заголовков ответа Web-сервера и двух отступов). В Delphi если к примеру отдаваемый HTML страницы содержится в Memo1, то длина контента может быть получена следующей строкой: Length(Memo1.Text)). При этом на момент написания данной статьи в 2020 году, я посмотрел какие заголовки отдаёт Web-сервер Apache при генерации страницы с помощью PHP(версия 5.4) и увидел следующие:

Как можно заметить среди указанных заголовков нет заголовка Length.

Комментарии

Если у Вас возникли вопросы, Вы можете задать их в форме ниже. В частности если Ваш вопрос по Bitrix и что то не получается - можно спросить. Ваш e-mail не публикуется, при этом я отвечу на него если будет что то по теме. Писать необходимо для людей - избегайте сленга, пишите орфографически правильно.

Имя:
E-mail:
Текст комментария:

Вы так же можете прочитать следующие статьи: