В Delphi документации по многопотоковому TServerSocket налито довольно много воды, и начинающему программисту сложно понять суть дела. Давайте попытаемся пролить немного света на этот раздел хелпа.
Вообще-то, создать многопотоковый сервер, который ожидает пришедшие сообщения на сокете довольно просто. В 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;
interfaceuses
windows, scktcomp, SysUtils, Classes, Forms;
type
EServerThread = class( Exception );
// serverthread это потомок TServerClientThread
TServerThread = class( TServerClientThread )
private
fSocketStream : TWinSocketStream;
publicprocedure ClientExecute; override;
// ClientExecute отменяет// TServerClientThread.ClientExecute// и содержит код, который// выполняется при старте потокаend;
implementationprocedure TServerThread.ClientExecute;
begininherited FreeOnTerminate := TRUE;
try
fSocketStream := TWinSocketStream.Create( ClientSocket, 100000 );
// 100000 - это таймаут в миллисекундах.trywhile ( not Terminated ) and ( ClientSocket.Connected ) dotry// В это место обычно помещается код,// ожидающий входных данных, читающий из сокета или пишущий в него// Пример, приведённый ниже, показывает, что можно добавить в данную// секцию программы.excepton e:exception dobegin// Если произошла ошибка, то закрываем сокет и выходим
ClientSocket.Close;
Terminate;
end;
end;
finally
fSocketStream.Free;
end;
excepton e:exception dobegin// Если произошла ошибка, то закрываем сокет и выходим
ClientSocket.Close;
Terminate;
end;
end;
end;
Когда связь установлена, потоку необходимо ожидать входящих данных(запроса от клиента). Для этого можно использовать следующий код:
if (not Terminated) and (not fSocketStream.WaitForData(1000000)) thenbegin// Обработчик таймаута (т.е. если по истечении 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 - это размер буфера.
Если Вас заинтересовала или понравилась информация по разработке на Delph - "Использование компонента TServerSocket", Вы можете поставить закладку в социальной сети или в своём блоге на данную страницу: Так же Вы можете задать вопрос по работе этого модуля или примера через форму обратной связи, в сообщение обязательно указывайте название или ссылку на статью!