Недавно добавленные исходники

•  3D Designer  829

•  Sik Screen Capture  571

•  Patch Maker  513

•  Айболит (remote control)  627

•  ListBox Drag & Drop  464

•  Доска для игры Реверси  8 587

•  Графические эффекты  560

•  Рисование по маске  441

•  Перетаскивание изображений  486

•  Canvas Drawing  487

•  Рисование Луны  379

•  Поворот изображения  259

•  Рисование стержней  314

•  Paint on Shape  189

•  Генератор кроссвордов  247

•  Головоломка Paletto  225

•  Теорема Монжа об окружностях  270

•  Пазл Numbrix  185

•  Заборы и коммивояжеры  302

•  Игра HIP  204

•  Игра Go (Го)  145

•  Симулятор лифта  180

•  Программа укладки плитки  165

•  Генератор лабиринта  204

•  Проверка числового ввода  193

•  HEX View  231

•  Физический маятник  202

•  Задача коммивояжера  233

•  Автомобильная пробка  156

•  Квадратные сетки из слов  127

 
скрыть


Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



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




Попал фидошник в ад. Ему черт говорит:
- Тебе определено 1000 лет наказания, но т. к. я люблю анекдоты, то разрешаю их тебе рассказывать. Пока ты их рассказываешь, этот срок будет вычтен из твоего наказания.
Ну, фидошник начинает травить анекдоты. Год... два... 100 лет... 900 лет прошло, он все рассказывает. Наконец, на 999 году замолкает.
- Все, анекдоты закончились? Ну, давай хоть год тебя помучаю.
- Да погоди ты, сейчас вторую часть офтопик-листа достану!

В 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;

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 - это размер буфера.





Похожие по теме исходники

Расширение компонента TEdit




Copyright © 2004-2021 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте   Facebook   Ссылка на Twitter   Ссылка на Telegram