МЕНЮ


Фестивали и конкурсы
Семинары
Издания
О МОДНТ
Приглашения
Поздравляем

НАУЧНЫЕ РАБОТЫ


  • Инновационный менеджмент
  • Инвестиции
  • ИГП
  • Земельное право
  • Журналистика
  • Жилищное право
  • Радиоэлектроника
  • Психология
  • Программирование и комп-ры
  • Предпринимательство
  • Право
  • Политология
  • Полиграфия
  • Педагогика
  • Оккультизм и уфология
  • Начертательная геометрия
  • Бухучет управленчучет
  • Биология
  • Бизнес-план
  • Безопасность жизнедеятельности
  • Банковское дело
  • АХД экпред финансы предприятий
  • Аудит
  • Ветеринария
  • Валютные отношения
  • Бухгалтерский учет и аудит
  • Ботаника и сельское хозяйство
  • Биржевое дело
  • Банковское дело
  • Астрономия
  • Архитектура
  • Арбитражный процесс
  • Безопасность жизнедеятельности
  • Административное право
  • Авиация и космонавтика
  • Кулинария
  • Наука и техника
  • Криминология
  • Криминалистика
  • Косметология
  • Коммуникации и связь
  • Кибернетика
  • Исторические личности
  • Информатика
  • Инвестиции
  • по Зоология
  • Журналистика
  • Карта сайта
  • Программирование на Delphi

    для установления соединения с клиентом. Это количество должно

    рассчитываться в зависимости от интенсивности и продолжительности контакта

    с клиентами. Лишние потоки поглощают системные ресурсы, в первую очередь

    память и процессорное время. Чтобы оптимизировать использование кэша

    свободных потоков, полезно поинтересоваться значением двух свойств:

    property ActiveThreads: Integer;

    property IdieThreads: Integer;

    показывающих число активных (занятых обслуживанием клиентов) и

    простаивающих (ожидающих) потоков соответственно.

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

    property OnThreadStart: TThreadNotifyEvent;

    property OnThreadEnd: TThreadNotifyEvent;

    type TTnreadNotifyEvent=procedure(Sender: TObject;

    Thread: TServerClientThread) of object;

    Чтобы избежать ситуаций тупиков или гонок при работе с сокетами, имеются

    два метода:

    procedure Lock;

    procedure Unlock;

    Если вами предусмотрен код, который может вызвать проблемы в многозадачной

    среде, заключите его между вызовами методов Lock и unlock — на это время

    остальные потоки, работающие с сокетами, будут блокированы.

    Методы чтения и записи для блокирующего и неблокирующего режима существенно

    отличаются. ассмотрим сначала те, что предназначены для неблокирующего

    (асинхронного) режима.

    Средства для организации чтения представлены группой из трех методов:

    function ReceiveLength: Integer;

    возвращает число байт, которые могут быть приняты в ответ на оповещение

    клиента о передаче

    function ReceiveText: string;

    возвращает прочитанную из сокета текстовую строку

    function ReceiveBuf(var Buf; Count:Integer): Integer;

    возвращает данные, прочитанные из сокета в буфер Buf, в количестве count

    байт

    Аналогично, методы:

    function SendBuf(var Buf; Count: Integer): Integer;

    procedure SendText(const S: string);

    function SendStream (AStream: TStream) : Boolean;

    посылают клиенту буфер, текстовую строку и поток данных. В дополнение к

    этому метод:

    function SendStrearoThenDrop (AStream: TStream): Boolean;

    посылает клиенту поток данных и завершает соединение.

    Передаваемый в качестве параметра последних двух функций поток данных

    AStream переходит "под надзор" объекта TServerWinsocket и удаляется им по

    мере пересылки. Программист не должен предпринимать попыток удалить AStream

    после вызова методов SendSrteam или SendSrteamThenDrop.

    При помощи метода:

    function GetClientThread(ClientSocket: TServerClientWinSocket):

    TServerClientThread;

    можно получить указатель на поток, занимающийся обслуживанием конкретного

    сокета.

    События:

    property OnClientConnect;

    property OnClientDisconnect;

    property OnClientRead;

    property OnClientWrite;

    имеют одинаковый тип:

    TSocketNotifyEvent=procedure(Sender: TObject;

    Socket: TCustomWinSocket) of object;

    Они происходят при соединении/отключении от клиента, а также при чтении и

    записи. Если произошла ошибка, возникает событие:

    property OnClientError; TSocketErrorEvent;

    type

    TErrorEvent = (eeGeneral, eeSend, eeReceive, eeConnect, eeDisconnect,

    eeAccept);

    TSocketErrorEvent = procedure (Sender: TObject;

    Socket: TCustomWinSocket;

    ErrorEvent: TErrorEvent;

    var ErrorCode: Integer) of object;

    Параметры его имеют следующее назначение. ErrorEvent указывает на тип

    операции, во время которой произошла ошибка. При этом ErrorCode содержит

    код ошибки Windows. Если вы сами обработали ошибку и не хотите дальнейших

    действий по ее обработке со стороны системы, нужно установить параметр

    ErrorCode в 0.

    Компонент TServerSocket

    Самое главное свойство этого компонента — уже упоминавшаяся ссылка на

    объект:

    property Socket: TServerWinSocket;

    Именно через него доступны все функциональные возможности сокета. Компонент

    же создан только для того, чтобы опубликовать необходимые свойства и

    события. В нем имеются свои события OnclientConnect, OnClientDisconnect,

    OnClientRead, OnClientWrite, OnClientError, но они не самостоятельны, а

    только отсылают к соответствующим событиям объекта TServerWinSocket. Также

    обстоит дело и со свойствами serverType и ThreadCacheSize.

    Дополнительно в компоненте предусмотрены события:

    property OnListen: TSocketNotifyEvent;

    происходит после того, как заданы адрес и порт сокета и перед тем, как он

    включается в режим прослушивания (готовности к соединению)

    property OnAccept: TSocketNotifyEvent;

    происходит непосредственно после установки соединения

    Свойство property Active: Boolean;

    отвечает за состояние сокета. Для клиентского сокета изменение его значения

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

    включение/выключение состояния прослушивания. Использование этого свойства

    равносильно применению следующих методов:

    procedure Open;

    procedure Close;

    Свойство property Service: string;

    служит для идентификации предназначения сокета. Здесь должно храниться

    символьное имя сервиса, для которого используется сокет (ftp, http, telnet

    и др.)

    Объект TClientWinSocket

    Многие из событий и методов этого объекта уже описаны выше (см. объект

    TServerwinSocket), так как они имеют общего предка. Но есть и различия,

    требующие комментария. Как и серверный, клиентский сокет может быть двух

    типов:

    type TCiientType = (ctNonBlocking, ctBlocking);

    property ClientType: TCiientType;

    В отличие от сервера, в блокировке клиента большой беды нет. Если

    установлен режим ctBlocking, клиентское приложение блокируется до

    завершения операции. В режиме ctNonBiocking операции выполняются

    асинхронно.

    Компонент TClientSocket

    Основное внимание при рассмотрении этого компонента обратим на логику

    событий, происходящих при подключении клиентского сокета к серверу. Она

    такова:

    1. Вызывается метод open (или свойство Active устанавливается в True).

    2. Перед началом инициализации происходит событие

    property onLookup: TSocketNotifyEvent;.

    В этот момент еще можно поменять свойства объекта TClieniwinSocket: адрес,

    номер порта и т. п.

    3. Сокет полностью инициализируется и начинает поиск. Когда серверный сокет

    обнаружен, происходит событие

    property onConneciing: TSocketNotifyEvent;.

    4. Когда клиентский запрос удовлетворен сервером и установлено соединение,

    происходит событие

    property OnConnect: TSocketNotifyEvent;

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

    Процесс подключения к серверу выглядит таким образом:

    procedure TClientForm.FileConnectltemClick(Sender: TObject);

    Begin

    if ClientSocket.Active then ClientSocket.Active := False;

    if InputQuery('Сервер', 'Адрес (имя)', Server) then

    if Length(Server)>0 then

    with ClientSocket do begin

    Host := Server;

    Active := True;

    end;

    End;

    После установления соединения клиент реагирует на событие onClientRead:

    procedure TCiientFom.ClientSocketRead(Sender: TObject; Socket:

    TCustomWinSocket);

    var s: string;

    Begin

    s:= Socket.ReceiveText;

    if ((s[l]='T') and (TimeSpeedButton.Down)) then

    TimeSpeedButton.Caption:=Copy(s, 2, Length(s))

    else if ((s[l]='M') and (MemSpeedButton. Down)) then

    KemSpeedButton.Caption:=Copy(s, 2, Length (s));

    End;

    В серверном приложении сокет устанавливается в активное состояние

    (прослушивание) при запуске программы. Все подключившиеся клиенты

    автоматически заносятся как элемент списка (свойство connections). Саму

    информацию о дате и времени сервер рассылает по таймеру в виде

    отформатированных текстовых строк:

    procedure TServerForm.TimerITimerlSender: TObject);

    var i: Integer;

    s: string;

    ms : TMemoryStatus;

    Begin

    with ServerSocket.Socket do

    for i:=0 to ActiveCcnnections-I do

    Connections[i].SendText('T'+TimeToStr(Now));

    GlobaiMemoryStatus(ms);

    s:=Format('%1OdK',[(ms.dwAvaiiPageFile + ms.dwAvaiiPhys) div 1024]); with

    ServerSocket.Socket do

    for i:=0 to ActiveConnections-I do

    Connections [ i ] . SendText ( ' M' +s ) ;

    End;

    Сервер может отреагировать на сообщение от клиента. Ответ следует

    отправлять через параметр socket произошедшего события onClientRead:

    procedure TServerForm.ServerSocketClientRead (Sender: TObject;

    Socket: TCustomWinSocket);

    Begin

    Memo1.Lines.Add(Socket. ReceiveText );

    Socket.SendText( ' I am understand' );

    End;

    К сокетам проявляют интерес многие разработчики, что можно объяснить их

    универсальностью и широким распространением. Если вы не нашли чего-то для

    вас необходимого в компонентах TClientSocket и TServerSocket, или наоборот

    — сочли их слишком сложными в применении, вы можете использовать компонент

    TPowersock, разработанный компанией NetMasters. Он находится также на

    странице Internet Панели инструментов.

    Совместное использование общей памяти

    Традиционным является метод межзадачного взаимодействия при помощи

    совместно используемой памяти. В DOS и 16-разрядной Windows он был простым

    и не требующим пояснений — у всех задач, в том числе у операционной

    системы, было общее адресное пространство. Но именно из этого проистекали

    все беды и проблемы данных ОС. В 32x разрядных версиях Windows у каждого

    приложения свое адресное пространство, недоступное другим приложениям. Тем

    не менее, способ обмена данными через память существует.

    Разделение данных осуществляется посредством отображения некоторого объема

    совместно используемой памяти в адресное пространство каждого приложения,

    участвующего в обмене. Память может быть разделяемой потому, что она

    фактически располагается вне адресного пространства приложения. Вообще

    говоря, в 32-разрядной Windows под "памятью" подразумевается не только

    оперативная память (ОЗУ), но также и память, резервируемая операционной

    системой на жестком диске. Этот вид памяти называется виртуальной памятью.

    Код и данные отображаются на жесткий диск посредством страничной системы

    (paging system) подкачки. Страничная система использует для отображения

    страничный файл (win386.swp в Windows 95 и pagefile.sys в Windows NT).

    Необходимый фрагмент виртуальной памяти переносится из страничного файла в

    ОЗУ и, таким образом, становится доступным.

    Для выделения фрагмента совместно используемой памяти должен быть создан

    специальный системный объект Win 32, называемый отображаемым файлом. Этот

    объект "знает", как соотнести файл, находящийся на жестком диске, с

    памятью, адресуемой процессами. В нашем случае файл, который мы посредством

    объекта файлового отображения хотим сделать доступным нашему приложению —

    это не файл с расширением ТХТ, DLL. или ЕХЕ. Это страничный файл подкачки,

    используемый системой. Отобразив фрагмент страничного файла в память,

    адресуемую нашим приложением, мы, по сути дела, получили фрагмент памяти,

    на который в дальнейшем будем ссылаться, как на данные объекта файлового

    отображения.

    Примечание. Объекты файлового отображения могут использоваться для

    отображения в память любого файла, а не только страничного файла

    операционной системы.

    Одно или более приложений могут открыть отображаемый файл и получить тем

    самым доступ к данным этого объекта. Таким образом, данные, помещенные в

    страничный файл приложением, использующим отображаемый файл, будут доступны

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

    файл.

    Разделение данных между приложениями осуществляется посредством

    использования функций API, предоставляемых Win 32 для создания и

    использования объектов файлового отображения. Вот наиболее важные из этих

    функций:

    CreateFileMapping

    MapViewOfFile

    UnMapViewOfFiie

    Создание объекта файлового отображения

    Отображаемый файл создается операционной системой при вызове функции

    CreateFileMapping. Этот объект поддерживает соответствие между содержимым

    файла и адресным пространством процесса, использующего этот файл. В нашем

    случае целью будет совместное использование данных. Страничный файл

    операционной системы используется как расширение памяти. Таким образом,

    создав отображаемый файл, связанный со страничным файлом операционной

    системы, мы имеем в качестве результата выделение глобально доступной

    памяти. Так как эта память является общедоступной, то другой экземпляр

    объекта файлового отображения, открытый программой, запущенной в качестве

    другого процесса, может иметь к ней доступ.

    Функция CreateFileMapping имеет шесть параметров:

    function CreateFileMapping (hFile: THandle;

    ipFileMappingAttributes: PSecurityAttributes;

    flProtect,

    dwMaximumSizeHign,

    dwMaximurnSizeLow: DWORD;

    lpName: PChar): THandle; stdcall;

    Первый параметр имеет тип THandle. Для наших целей значение этого параметра

    всегда должно быть $FFFFFFFF (значок "$" указывает на то, что значение

    шестнадцатеричное). В принципе на этом месте должен стоять дескриптор уже

    открытого при помощи функции CreateFile файла; но, поскольку мы имеем дело

    с необычным файлом, указание значения $FFFFFFFF приводит к связыванию

    объекта файлового отображения именно со страничным файлом операционной

    системы.

    Второй параметр — указатель на запись типа TSecurityAttributes. В нашем

    случае значение этого параметра всегда равно nil. Третий параметр имеет тип

    dword. Он определяет атрибут защиты. Чтобы при помощи отображаемого файла

    организовать совместное использование данных, третьему параметру следует

    присвоить значение PAGE_READWRITE.

    Четвертый и пятый параметры также имеют тип dword. В 32-разрядной

    операционной системе значение dword имеет дайну 32 бита. Когда выполняется

    функция CreateFileMapping, значение типа dword четвертого параметра

    сдвигается влево на четыре байта и затем объединяется со значением пятого

    параметра посредством операции and. Проще говоря, значения объединяются в

    одно 64-разрядное число, равное объему памяти, выделяемой объекту файлового

    отображения из страничного файла операционной системы.

    Поскольку вы вряд ли попытаетесь осуществить выделение более чем четырех

    гигабайт данных, то значение четвертого параметра всегда должно быть равно

    нулю. Используемый затем пятый параметр должен показывать, сколько памяти в

    байтах необходимо зарезервировать в качестве совместной.

    Шестой параметр имеет тип pСhar. Это значение представляет собой имя

    объекта файлового отображения, которое должно быть уникальным.

    Функция СreateFileMapping возвращает значение типа THandle. В случае

    успешного завершения возвращаемое функцией значение представляет собой

    дескриптор созданного объекта файлового отображения. В случае возникновения

    какой-либо ошибки возвращаемое значение будет равно 0.

    Следующий фрагмент кода демонстрирует использование функции

    СreateFileMapping:

    var

    hMappedFiie: THandie;

    Begin

    hMappedFile:=CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,

    25, 'SharedBiock');

    if (hMappedFiie = 0) then ShowMessage('Mapping error ! ');

    End;

    В этом примере функция выделяет 25 байт. езультирующий отображаемый файл

    называется SharedBlock. В случае успеха функция вернет описатель текущего

    объекта файлового отображения в переменную hFileMapObj. Переменная

    hFileMapObj имеет тип THandie. Если переменная hFileMapObj равна нулю, то

    это значит, что функция завершилась с ошибкой, о чем будет выведено

    соответствующее сообщение.

    Подключение объекта файлового отображения к адресному пространству

    При помощи функции CreateFileMapping мы только создали объект типа

    "отображаемый файл"; следующая задача — спроецировать данные файла в

    адресное пространство нашего процесса. Этой цели служит функция

    MapViewOfFile. Функция MapViewOfFile имеет пять параметров:

    function MapViewOfFile(hFileMappingObject: THandie;

    dwDesiredAccess: DWORD;

    dwFileOffsetHigh,

    dwFiieOffsetLow,

    dwIMumberOfBytesToMap: DWORD): Pointer; stdcall;

    Первый параметр имеет тип THandle. Его значением должен быть дескриптор

    созданного объекта файлового отображения — тот, который возвращает функция

    CreateFileMapping. Второй параметр имеет тип dword. Его значение должно

    быть установлено в FILE_MAP_WRITE (или. что то же самое, в

    FILE_MAP_ALL_ACCESS); это означает, что данные объекта файлового

    отображения будут доступны как по считыванию, так и по записи.

    Третий и четвертый параметры также имеют тип dword. Это — смещение

    отображаемого участка относительно начала файла в байтах. В нашем случае

    эти параметры должны быть установлены в нуль, поскольку значение, которое

    мы даем пятому (последнему) параметру функции MapViewOfFile, также равно

    нулю.

    Пятый и последний параметр функции MapViewOfFile, как и предыдущие

    параметры, имеет тип dword. Он используется для определения (в байтах)

    количества данных объекта файлового отображения, которые надо отобразить в

    процесс (сделать доступными для вас). Для достижения наших целей это

    значение должно быть установлено в нуль, что означает автоматическое

    отображение в процесс всех данных, выделенных перед этим функцией

    CreateFileMapping.

    Значение, возвращаемое функцией MapViewOfFile, имеет тип "указатель". Если

    функция отработала успешно, то она вернет начальный адрес данных объекта

    файлового отображения.

    Следующий фрагмент кода демонстрирует вызов функции MapViewOfFile:

    var

    hMappedFile: THandie;

    pSharedBuf: PChar;

    Begin

    hMappedFile:=CreateFileMapping ($FFFFFFFF, nil, PAGE_READWRITE, 0,

    Страницы: 1, 2, 3, 4, 5, 6, 7


    Приглашения

    09.12.2013 - 16.12.2013

    Международный конкурс хореографического искусства в рамках Международного фестиваля искусств «РОЖДЕСТВЕНСКАЯ АНДОРРА»

    09.12.2013 - 16.12.2013

    Международный конкурс хорового искусства в АНДОРРЕ «РОЖДЕСТВЕНСКАЯ АНДОРРА»




    Copyright © 2012 г.
    При использовании материалов - ссылка на сайт обязательна.