Читаем О чём не пишут в книгах по Delphi полностью

Так как многие функции библиотеки сокетов блокируют вызвавшую их нить, если соответствующая операция не может быть выполнена немедленно, часто бывает полезно заранее знать, готов ли сокет к немедленному (без блокирования) выполнению той или иной операции. Основным средством определения этого в библиотеке сокетов служит функция select:

function select(nfds: Integer; readfds, writefds, exceptfds: PFDSet; timeout: PTimeVal): LongInt;

Первый параметр этой функции оставлен только для совместимости со старыми версиями библиотеки сокетов: в существующих версиях он игнорируется. Три следующих параметра содержат указатели на множества сокетов (эти множества описываются типом TFDSet), состояние которых должно проверяться. В данном случае понятие множества не имеет ничего общего с типом множество в Delphi. В оригинальной версии библиотеки сокетов, написанной на C, определены макросы, позволяющие очищать такие множества, добавлять и удалять сокеты и определять, входит ли тот или иной сокет в множество. В модуле WinSock эти макросы заменены одноименными процедурами и функциями (листинг 2.22).

Листинг 2.22. Функции для работы с типом TFDSet

// Удаляет сокет Socket из множества FDSet.

procedure FD_CLR(Socket: TSocket; var FDSet: TFDSet);

// Определяет, входит ли сокет Socket в множество FDSet.

function FD_ISSET(Socket: TSocket; var FDSet: TFDSet): Boolean;

// Добавляет сокет Socket в множество FDSet.

procedure FD_SET(Socket: TSocket; var FDSet: TFDSet);

// Инициализирует множество FDSet.

procedure FD_ZERO(var FDSet: TFDSet);

При создании переменной типа TFDSet в той области памяти, которую она занимает, могут находиться произвольные данные, являющиеся, по сути дела, "мусором". Из-за этого мусора функции FD_CLR, FD_ISSET, и FD_SET не смогут работать корректно. Процедура FD_ZERO очищает мусор, создавая пустое множество. Вызов остальных функций FD_XXX до вызова FD_ZERO приведёт к непредсказуемым результатам.

Мы намеренно не приводим здесь описание внутренней структуры типа TFDSet. С помощью функций FD_XXX можно выполнить все необходимые операции с множеством, не зная этой структуры. Отметим, что в Windows и в Unix внутреннее устройство этого типа существенно различается, но благодаря использованию этих функций код остается переносимым.

В Windows максимальное количество сокетов, которое может содержать в себе множество TFDSet, определяется значением константы FD_SETSIZE. По умолчанию ее значение равно 64. В C/C++ отсутствует раздельная компиляция модулей в том смысле, в котором она существует в Delphi, поэтому модуль в этих языках может поменять значение константы FD_SETSIZE перед включением заголовочного файла библиотеки сокетов, и это изменение приведёт к изменению внутренней структуры типа TFDSet (точнее, типа FDSet — в C/C++ он называется так). К счастью, в Delphi модули надежно защищены от подобного влияния друг на друга, поэтому как бы мы ни переопределяли константу FD_SETSIZE в своем модуле, на модуле WinSock это никак не отразится. В Delphi приходится прибегать к другому способу изменения количества сокетов в множестве: для этого следует определить свой тип, эквивалентный по структуре TFDSet, но резервирующий иное количество памяти для хранения сокетов (структуру TFDSet можно узнать из исходного кода модуля WinSock). В функцию select можно передавать указатели на структуры нового типа, необходимо только приведение типов указателей. А вот существующие функции FD_XXX, к сожалению, не смогут работать с новой структурой, потому что компилятор требует строгого соответствия типов для параметров-переменных. Но, опять же, при необходимости очень легко создать аналоги этих функций для своей структуры.

Примечание

На первый взгляд может показаться, что Delphi в данном случае хуже, чем C/C++. Но достаточно хотя бы раз столкнуться с ошибкой, вызванной взаимным влиянием макроопределений в модулях C/C++, чтобы понять, что уж лучше написать несколько лишних строк кода, лишь бы никогда больше не иметь таких проблем.

Последний параметр функции select содержит указатель на структуру TTimeVal, которая описывается следующим образом:

Перейти на страницу:

Похожие книги

1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных