Суббота, 18.05.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Нравится раздел статьи?
Всего ответов: 68
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Сеть-интернет » Разные

Использование компонента TServerSocket

В Delphi документации по многопотоковому TServerSocket налито довольно много воды, и начинающему программисту сложно понять суть дела. Давайте попытаемся пролить немного света на этот раздел хелпа.

Совместимость: Delphi 3.x (или выше)

Вообще-то, создать многопотоковый сервер, который ожидает пришедшие сообщения на сокете довольно просто. В Delphi для этой цели достаточно использовать компонент TServerSocket.

Давайте рассмотрим структуру работы данного компонента:

- Добавляем TServerSocket в Вашу основную форму.
- Устанавливаем свойство Servertype в stThreadBlocking
- Создаём новый "unit" (показанный ниже) содержащий поток сервера.

Устанавливаем следующий код на OnSocketGetThread

procedure TfrmMain.fSocketGetThread(Sender: TObject;
 ClientSocket: TServerClientWinSocket;
 var SocketThread: TServerClientThread);
begin
 // Здесь создаём объект TServerThread, который я привожу ниже.
 // Новый объект создаётся каждый раз, когда когда установлен канал связи. 
 SocketThread := TServerThread.Create( FALSE, ClientSocket );
end; 

TServerThread - это объект, который я создаю самостоятельно. Объект наследуется от TServerClientThread и содержит код, который обычно читает и пишет данные из/в сокет.

Созданный "unit", содержит следующий код:

unit serverthread;

interface

uses
 windows, scktcomp, SysUtils, Classes, Forms;

type
 EServerThread = class( Exception );
 // serverthread это потомок TServerClientThread
 TServerThread = class( TServerClientThread )
 private
 fSocketStream : TWinSocketStream;
 public
 procedure ClientExecute; override;
 // ClientExecute отменяет
 // TServerClientThread.ClientExecute
 // и содержит код, который
 // выполняется при старте потока
 end;

implementation

procedure TServerThread.ClientExecute;
begin
 inherited FreeOnTerminate := TRUE;
 try
 fSocketStream := TWinSocketStream.Create( ClientSocket,
 100000 );
 // 100000 - это таймаут в миллисекундах.
 try
 while ( not Terminated ) and ( ClientSocket.Connected ) do
 try
 // В это место обычно помещается код,
 // ожидающий входных данных, читающий из сокета или пишущий в него
 // Пример, приведённый ниже, показывает, что можно добавить в данную
 // секцию программы.
 except on e:exception do
 begin
 // Если произошла ошибка, то закрываем сокет и выходим
 ClientSocket.Close;
 Terminate;
 end;
 end;
 finally
 fSocketStream.Free;
 end;
 except on e:exception do
 begin
 // Если произошла ошибка, то закрываем сокет и выходим
 ClientSocket.Close;
 Terminate;
 end;
 end;
end; 

Когда связь установлена, потоку необходимо ожидать входящих данных(запроса от клиента). Для этого можно использовать следующий код:

if ( not Terminated ) and
 ( not fSocketStream.WaitForData( 1000000 ) ) then
begin
 // Обработчик таймаута (т.е. если по истечении 1000000 миллисекунд
 // от клиента не пришло запроса
end;
// В сокете есть входящие данные! 

Для чтения данных, Вам понадобится создать буфер для хранения полученных данных. Обычно буфер - это PByteArray или массив символов. В этом примере я обозвал буфер как fRequest который является массивом символов. Кроме того я ожидаю фиксированное количество байт. Массив имеет постоянный размер REQUESTSIZE.

var
 ac, readlen : integer;
begin
 FillChar( fRequest, REQUESTSIZE, 0 );
 ac := 0;
 repeat
 readlen := fSocketStream.Read( fRequest[ac],
 1024 );
 // считываем блоки по 1024 байт, до тех пор, пока буфер
 // не заполнится
 ac := ac+readlen;
 until ( readlen = 0 ) or ( ac = REQUESTSIZE );
end; 

Если readlen равно 0, значит больше нет входящих данных. Функция Чтения завершается через 100000 миллисекунд после запуска в TWinSocketStream.Create(). Если Вы не знаете сколько времени нужно ожидать запроса от клиента, то чем меньше будет таймаут, тем лучше. В большинстве случаев максимальный таймаут не должен превышать 30 секунд.

При посылке ответа, Вы должны знать, в каком режиме работает клиент. Многие клиенты ожидают только один пакет ответа, другие ожидают несколько пакетов. В этом примере, я подразумеваю клиента, который ожидает только один пакет, так что я должен послать мои данные назад в одном блоке:

fSocketStream.WriteBuffer( fRep, fReplySize ); 

fRep это буфер, содержащий ответ на запрос клиента, и fReplySize - это размер буфера.

Получить ссылку на материал

Категория: Разные | Добавил: Барон (14.12.2011)
Просмотров: 1007 | Теги: TServerSocket, компонент | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
Web-приложения [6]
Почта [12]
Работа с HTTP [4]
Робота с XML [4]
Сервер [3]
Разные [50]
Королевство Delphi © 2010-2024
Яндекс цитирования