Главная    Почта    Новости    Каталог    Одноклассники    Погода    Работа    Игры     Рефераты     Карты
  
по Казнету new!
по каталогу
в рефератах

Программирование на Delphi

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


property OnGetThread: TGetThreadEvent;

type TGetThreadEvent = procedure (Sender: TObject;

ClientSocket:        TServerClientWinSocket;        var        SocketThread:
TServerCiientThread) of object;
В отличие от stThreadBlocking, тип stNonBlocking своим поведением  ничем  не
отличается  от  описанного  выше  —  операции   происходят   асинхронно,   и
программист должен лишь описать реакцию на события, возникающие в момент  их
окончания.
Как известно, создание и уничтожение нового программного  потока  влечет  за
собой определенные системные накладные  расходы.  Чтобы  избежать  этого,  в
рассматриваемом  объекте  ведется  кэш  потоков.  По  завершении  соединения
потоки  не  уничтожаются,  а  переводятся  в   состояние   ожидания   нового
соединения.
Свойство: property ThreadCacheSize: Integer;
задает количество свободных потоков, которые могут находиться  в  готовности
для   установления   соединения   с   клиентом.   Это   количество    должно
рассчитываться в зависимости от интенсивности и  продолжительности  контакта
с клиентами. Лишние потоки поглощают системные  ресурсы,  в  первую  очередь
память  и  процессорное  время.  Чтобы  оптимизировать  использование   кэша
свободных потоков, полезно поинтересоваться значением двух свойств:


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,  или  наоборот
— сочли их слишком слож
Пред.678910След.
скачать работу

Программирование на Delphi

 

Отправка СМС бесплатно

На правах рекламы


ZERO.kz
 
Модератор сайта RESURS.KZ