А. Григорьев - О чём не пишут в книгах по Delphi

Тут можно читать онлайн А. Григорьев - О чём не пишут в книгах по Delphi - бесплатно ознакомительный отрывок. Жанр: comp-programming, издательство БХВ-Петербург, год 2008. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    О чём не пишут в книгах по Delphi
  • Автор:
  • Жанр:
  • Издательство:
    БХВ-Петербург
  • Год:
    2008
  • Город:
    СПб
  • ISBN:
    978-5-9775-019003
  • Рейтинг:
    4.25/5. Голосов: 81
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

А. Григорьев - О чём не пишут в книгах по Delphi краткое содержание

О чём не пишут в книгах по Delphi - описание и краткое содержание, автор А. Григорьев, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Рассмотрены малоосвещённые вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные механизмы их работы, особенности для протоколов TCP и UDP и др. Большое внимание уделено разбору ситуаций возникновения ошибок и получения неверных результатов в "простом и правильном" коде. Отдельно рассмотрены особенности работы с целыми, вещественными и строковыми типами данных, а также приведены примеры неверных результатов, связанных с ошибками компилятора, VCL и др. Для каждой из таких ситуаций предложены методы решения проблемы. Подробно рассмотрен синтаксический анализ в Delphi на примере арифметических выражений. Многочисленные примеры составлены с учётом различных версий: от Delphi 3 до Delphi 2007. Прилагаемый компакт-диск содержит примеры из книги.

Для программистов

О чём не пишут в книгах по Delphi - читать онлайн бесплатно ознакомительный отрывок

О чём не пишут в книгах по Delphi - читать книгу онлайн бесплатно (ознакомительный отрывок), автор А. Григорьев
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

begin

MessageDlg('Номер порта должен находиться в диапазоне 1-65535',

mtError, [mbOK], 0);

Exit;

end;

// Создание сокета

ServerSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if ServerSocket = INVALID_SOCKET then

begin

MessageDlg('Ошибка при создании сокета: '#13#10 + GetErrorString,

mtError, [mbOK], 0);

Exit;

end;

// Привязка сокета к адресу

if bind(ServerSocket, ServerAddr, SizeOf(ServerAddr)) = SOCKET_ERROR then

begin

MessageDlg('Ошибка при привязке сокета к адресу: '#13#10 +

GetErrorString, mtError, [mbOK], 0);

closesocket(ServerSocket);

Exit;

end;

// Перевод сокета в режим прослушивания

if listen(ServerSocket, SOMAXCONN) = SOCKET_ERROR then

begin

MessageDlg('Ошибка при переводе сокета в режим просушивания:'#13#10 +

GetErrorString, mtError, [mbOK], 0);

closesocket(ServerSocket);

Exit;

end;

// Запуск нити, обслуживающей слушающий сокет

TListenThread.Create(ServerSocket);

// Перевод элементов управления в состояние "Сервер работает"

LabelPortNumber.Enabled := False;

EditРоrtNumber.Enabled := False;

BtnStartServer.Enabled := False;

LabelServerState.Caption := 'Сервер работает';

except

on EConvertError do

// Это исключение может возникнуть только в одном месте

// при вызове StrToInt(EditPortNumber.Text)

MessageDlg('"' + EditPortNumber.Text + '"не является целым числом',

mtError, [mbOK], 0);

on ERangeError do

// это исключение может возникнуть только в одном месте -

// при присваивании значения номеру порта

MessageDlg('Номер порта должен находиться в диапазоне 1-65535',

mtError, [mbOK], 0);

end;

end;

Слушающая" нить TListenThreadсостоит из бесконечного ожидания подключения клиента. Каждый раз при подключении клиента библиотека сокетов создаёт новый сокет, и для работы с ним создается новая нить типа TClientThread(листинг 2.20).

Листинг 2.20. Код "слушающей" нити

procedure TListenThread.Execute;

// Сокет, созданный для общения с подключившимся клиентом

ClientSocket: TSocket;

// Адрес подключившегося клиента

ClientAddr: TSockAddr;

ClientAddrLen: Integer;

begin

// Начинаем бесконечный цикл

repeat

ClientAddrLen := SizeOf(ClientAddr);

// Ожидаем подключения клиента

ClientSocket := accept(FServerSocket, @ClientAddr, @ClientAddrLen);

if ClientSocket = INVALID_SOCKET then

begin

// Ошибка в функции accept возникает только тогда, когда

// происходит нечто экстраординарное. Продолжать работу

// в этом случае бессмысленно.

LogMessage('Ошибка при подключении клиента: ' + GetErrorString);

Break;

end;

// Создаем новую нить для обслуживания подключившегося клиента

// и передаём ей сокет, созданный для взаимодействия с ним.

TClientThread.Create(ClientSocket, ClientAddr);

until False;

closesocket(FServerSocket);

LogMessage('Сервер завершил работу');

Synchronize(ServerForm.OnStopServer);

end;

Метод LogMessage, существующий у "слушающей" нити, эквивалентен тому, который приведен в листинге 2.7.

Код нити типа TClientThread, которая отвечает за взаимодействие с одним клиентом, приведен в листинге 2.21.

Листинг 2.21. Код нити, реализующей взаимодействие с клиентом

// Сокет для взаимодействия с клиентом создается в главной нити,

// а сюда передается через параметр конструктора. Для формирования

// заголовка сюда же передается адрес подключившегося клиента

constructor TClientThread.Create(ClientSocket: TSocket; const ClientAddr:TSockAddr);

begin

FSocket := ClientSocket;

// Заголовок содержит адрес и номер порта клиента.

// Этот заголовок будет добавляться ко всем сообщениям в лог

// от данного клиента.

FHeader :=

'Сообщение от клиента ' + inet_ntoa(ClientAddr.sin_addr) + ':' +

IntToStr(ntohs(ClientAddr.sin_port)) + ': ';

inherited Create(False);

end;

procedure TClientThread.Execute; var Str: string; StrLen: Integer;

begin

LogMessage('Соединение установлено');

// Начинаем цикл, из которого выходим только при закрытии

// соединения клиентом или из-за ошибки в сети.

repeat

// Читаем длину присланной клиентом строки и помещаем ее в StrLen

case ReadFromSocket(FSocket, StrLen, SizeOf(StrLen)) of

0: begin

LogMessage('Клиент закрыл соединение');

Break;

end;

-1: begin

LogMessage('Ошибка при получении данных от клиента: ' +

GetErrorString);

Break;

end;

end;

// Протокол не допускает строк нулевой длины

if StrLen <= 0 then

begin

LogMessage('Неверная длина строки от клиента: ' +

IntToStr(StrLen));

Break;

end;

// Установка длины строки в соответствии с полученным значением

SetLength(Str, StrLen);

// Чтение строки нужной длины

case ReadFromSocket(FSocket, Str[1], StrLen) of

0: begin

LogMessage('Клиент закрыл соединение');

Break;

end;

-1: begin

LogMessage('Ошибка при получении данных от клиента: ' +

GetErrorString);

Break;

end;

end;

LogMessage('Получена строка: ' + Str);

// Преобразование строки

Str :=

AnsiUpperCase(StringReplace(Str, #0, '#0', [rfReplaceAll]),

' (Multithreaded server)';

// Отправка строки. Отправляется на один байт больше, чем

// длина строки, чтобы завершающий символ #0 тоже попал в пакет

if send(FSocket, Str[1], Length(Str) + 1, 0) < 0 then

begin

LogMessage('Ошибка при отправке данных клиенту: ' +

GetErrorString);

Break;

end;

LogMessage('Клиенту отправлен ответ: ' + Str);

until False;

closesocket(FSocket);

end;

procedure TClientThread.LogMessage(const Msg: string);

begin

FMessage := FHeader + Msg;

Synchronize(DoLogMessage);

end;

Метод LogMessageздесь несколько видоизменен по сравнению с предыдущими примерами: к каждому сообщению он добавляет адрес клиента, чтобы пользователь мог видеть, с каким именно из одновременно подключившихся клиентов связано сообщение. Что же касается кода Execute, то видно, что он практически не отличается от кода внутреннего цикла простейшего сервера (см. листинг 2.15). Это неудивительно — сообщение здесь читается и обрабатывается единым образом. Вся разница только в том, что теперь у нас одновременно могут работать несколько таких нитей, обеспечивая одновременную работу сервера с несколькими клиентами.

Этот сервер уже можно использовать как образец для подражания. Нужно только помнить, что он тратит на каждого клиента относительно много ресурсов, и поэтому не подходит там, где могут подключаться сотни и более клиентов одновременно. Кроме того, этот сервер очень уязвим по отношению к DoS-атакам, поэтому подобный сервер целесообразен там. где число клиентов относительно невелико, а вероятность DoS-атак низка.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


А. Григорьев читать все книги автора по порядку

А. Григорьев - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




О чём не пишут в книгах по Delphi отзывы


Отзывы читателей о книге О чём не пишут в книгах по Delphi, автор: А. Григорьев. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x