Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС 2017
выпущен 15 марта!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

БОЛЬШОЙ FAQ ПО DELPHI



Формулы передачи данных для начинающих

Юзер - супорту:
- A чего это я постоянно слетаю с ваших модемов?!
- Летаешь - значит растешь!

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

Каково различие между KBps и Kbps? В чём заключается отличие битов, байтов и бодов? Как определить скорость передачи данных? Как выяснить, насколько долго будет загружаться файл с определённой скоростью? Как посчитать время, оставшее до окончания загрузки?

Для начала хотельсы навести порядок с некоторой неразберихой по поводу KBps и Kbps (буква b в нижнем регистре). KBps это обозначение для килобайт в секунду, в то время как Kbps обозначает килобиты в секунду. 1 килобайт (KB) = 8 килобитам (Kb).

Когда речь идёт о скорости передачи, то применяется Kbps. Таким образом модем со скорость передачи 33.6K (33600 bps) передаёт данные со скоростью 4.2 KBps (4.2 килобайта в секунду). Как мы видим, разница между KB и Kb довольно ощутима. В этом кроется причина того, что некоторые пользователи модемов по своему незнанию не могут понять, почему данные передаются так медленно. На самом деле данные объёмом 33.6K передаются не за 1 секунду, а за 8, соответственно за одну секунду будет передано 33.6 Kb / 8 = 4.2.

Так же хотелось бы дать некоторые разъяснения по поводу слова "бод" (baud). Обычно для модема "боды" расшифровываются как бит в секунду. На самом деле это не так. Бод (Baud) означает частоту звука в телефонной линии. Т. е. в зависимости от модема, который Вы используете, количество бит, которые могут быть переданы зависит от частоты звука, необходимой для обеспечения нужной скорости передачи.

Обратите внимание: Приведённый ниже пример, использует компонент NetMasters TNMHTTP. Однако, если Вы "прикипели" к какому-то другому компоненту TCP/IP, то переделать пример под этот компонент не составит большого труда.

Используемые обозначения:

bps
байт, переданных за 1 секунду
KBps (KB/Sec)
bps / 1024
Kbps (Kb/Sec)
KBps x 8

Краткий алгоритм приведённого ниже примера:

  1. Сохраняем в переменной время начала загрузки: nStartTime := GetTickCount;
  2. Сохраняем в переменной размер файла (KB): nFileSize := "File Size";
  3. Начало передачи данных.
  4. Обновляем количество переданных байт: Inc(nBytesTransferred, nNewBytes);
  5. Получаем оставшееся время: nTimeElapsed := (GetTickCount - nStartTime) / 1000;
  6. Вычисляем bps: nBps := BytesTransferred / nTimeElapsed;
  7. Вычисляем KBps: nKBps := nBps / 1024;

Используемые данные:


 Общее время скачивания (секунд) := nFileSize / nKBps;
 bps := FloatToStr(nBps);
 KB/Sec (KBps) := FloatToStr(nKBps);
 Осталось секунд := FloatToStr(((nFileSize - BytesTransferred) / 1024) / KBps);
 

Рабочий пример:


 unit Main;
 
 interface
 
 uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   StdCtrls, Gauges, Psock, NMHttp;
 
 type
   TfMain = class(TForm)
     Label1: TLabel;
     eURL: TEdit;
     bGet: TButton;
     lbMessages: TListBox;
     gbDetails: TGroupBox;
     lEstimate: TLabel;
     lKBps: TLabel;
     lReceived: TLabel;
     lRemaining: TLabel;
     gProgress: TGauge;
     NMHTTP1: TNMHTTP;
     lbps: TLabel;
     bCancel: TButton;
     procedure NMHTTP1PacketRecvd(Sender: TObject);
     procedure bGetClick(Sender: TObject);
     procedure bCancelClick(Sender: TObject);
     procedure NMHTTP1Connect(Sender: TObject);
     procedure NMHTTP1ConnectionFailed(Sender: TObject);
     procedure NMHTTP1Disconnect(Sender: TObject);
     procedure NMHTTP1Failure(Cmd: CmdType);
     procedure NMHTTP1HostResolved(Sender: TComponent);
     procedure NMHTTP1InvalidHost(var Handled: Boolean);
     procedure NMHTTP1Status(Sender: TComponent; Status: string);
     procedure NMHTTP1Success(Cmd: CmdType);
   private
     { Private declarations }
     function ss2nn(Seconds: Integer): string;
   public
     { Public declarations }
 end;
 
 var
   fMain: TfMain;
   nFileSize: Double;
   nStartTime: DWord;
 
 implementation
 
 {$R *.DFM}
 
 {Цель этой функции состоит в том, чтобы определить,
 сколько минут и секунд там находятся в данном количестве секунд}
 function TfMain.ss2nn(Seconds: Integer): string;
 var
   nMin, nSec: Integer;
 begin
   {Проверяем, меньше чем 1/Min}
   if Seconds < 60 then
     Result := '0 minutes ' + IntToStr(Seconds) + ' seconds'
   else
   begin
     {Определяем минуты}
     nMin := Seconds div 60;
     {Определяем секунды}
     nSec := Seconds - (nMin * 60);
     {Возвращаем результат}
     Result := IntToStr(nMin) + ' minutes ' + IntToStr(nSec) + ' seconds';
   end;
 end;
 
 procedure TfMain.NMHTTP1PacketRecvd(Sender: TObject);
 var
   nBytesReceived, nTimeElapsed, nBps, nKBps: Double;
 begin
   {Следующий код выполняется только однажды, при приёме первого пакета}
   if nFileSize <> NMHTTP1.BytesTotal then
   begin
     {Получаем размер файла}
     nFileSize := NMHTTP1.BytesTotal;
     {Вычисляем время передачи, исходя из скорости соединения 33.6 Kbps}
     lEstimate.Caption := 'Estimated download time at 33.6 Kbps: ' + ss2nn(Round(
     (nFileSize / 1024) / 4.2));
     {Получаем время начала}
     nStartTime := GetTickCount;
   end;
 
   {Обновляем nBytesReceived}
   nBytesReceived := NMHTTP1.BytesRecvd;
 
   {Вычисляем количество секунд прошедших с момента начала передачи}
   nTimeElapsed := (GetTickCount - nStartTime) / 1000;
   {Проверяем на 0/Sec, если так, то устанавливаем 1,
   чтобы предотвратить деления на ноль}
   if nTimeElapsed = 0 then
     nTimeElapsed := 1;
 
   {Вычисляем байт в секунду}
   nBps := nBytesReceived / nTimeElapsed;
   {Вычисляем килобайт в секунду}
   nKBps := nBps / 1024;
 
   {Обновляем контролы}
   gProgress.Progress := Round((nBytesReceived * 100) / nFileSize);
   lbps.Caption := IntToStr(Round(nBps * 8)) + ' bits per second';
   lKBps.Caption := IntToStr(Round(nKBps)) + ' KB/Sec (KBps)';
   lReceived.Caption := FloatToStr(nBytesReceived) + ' of ' + FloatToStr(
   nFileSize) + ' bytes received';
   lRemaining.Caption := ss2nn(Round(((nFileSize - nBytesReceived) / 1024) /
   nKBps)) + ' remaining';
 end;
 
 procedure TfMain.bGetClick(Sender: TObject);
 begin
   {Сбрасываем переменные}
   nFileSize := 0;
 
   {Обнуляем контролы}
   lbMessages.Clear;
   gProgress.Progress := 0;
   lEstimate.Caption := 'Estimated download time at 33.6 Kbps: 0 minutes 0 ' +
   'seconds';
   lbps.Caption := '0 bits per second';
   lKBps.Caption := '0 KB/Sec (KBps)';
   lReceived.Caption := '0 of 0 bytes received';
   lRemaining.Caption := '0 minutes 0 seconds remaining';
 
   {Получаем файл}
   NMHTTP1.Get(eURL.Text);
 end;
 
 procedure TfMain.bCancelClick(Sender: TObject);
 begin
   {Разрываем соединение с сервером}
   NMHTTP1.Disconnect;
 
   {Обновляем lbMessages}
   lbMessages.Items.Append('Get Canceled');
   lbMessages.Items.Append('Disconnected');
 end;
 
 procedure TfMain.NMHTTP1Connect(Sender: TObject);
 begin
   {Запрещаем/Разрешаем контролы}
   bGet.Enabled := False;
   bCancel.Enabled := True;
 
   {Работаем с lbMessages}
   with lbMessages.Items do
   begin
     Append('Connected');
     Append('Local Address: ' + NMHTTP1.LocalIP);
     Append('Remote Address: ' + NMHTTP1.RemoteIP);
   end;
 end;
 
 procedure TfMain.NMHTTP1ConnectionFailed(Sender: TObject);
 begin
   ShowMessage('Connection Failed.');
 end;
 
 procedure TfMain.NMHTTP1Disconnect(Sender: TObject);
 begin
   {Запрещаем/Разрешаем контролы}
   bCancel.Enabled := False;
   bGet.Enabled := True;
 
   {Обновляем lbMessages}
   if NMHTTP1.Connected then
     lbMessages.Items.Append('Disconnected');
 end;
 
 procedure TfMain.NMHTTP1Failure(Cmd: CmdType);
 begin
   case Cmd of
     CmdGET     : lbMessages.Items.Append('Get Failed');
     CmdOPTIONS : lbMessages.Items.Append('Options Failed');
     CmdHEAD    : lbMessages.Items.Append('Head Failed');
     CmdPOST    : lbMessages.Items.Append('Post Failed');
     CmdPUT     : lbMessages.Items.Append('Put Failed');
     CmdPATCH   : lbMessages.Items.Append('Patch Failed');
     CmdCOPY    : lbMessages.Items.Append('Copy Failed');
     CmdMOVE    : lbMessages.Items.Append('Move Failed');
     CmdDELETE  : lbMessages.Items.Append('Delete Failed');
     CmdLINK    : lbMessages.Items.Append('Link Failed');
     CmdUNLINK  : lbMessages.Items.Append('UnLink Failed');
     CmdTRACE   : lbMessages.Items.Append('Trace Failed');
     CmdWRAPPED : lbMessages.Items.Append('Wrapped Failed');
   end;
 end;
 
 procedure TfMain.NMHTTP1HostResolved(Sender: TComponent);
 begin
   lbMessages.Items.Append('Host Resolved');
 end;
 
 procedure TfMain.NMHTTP1InvalidHost(var Handled: Boolean);
 begin
   ShowMessage('Invalid Host. Please specify a new URL.');
 end;
 
 procedure TfMain.NMHTTP1Status(Sender: TComponent; Status: string);
 begin
   if NMHTTP1.ReplyNumber = 404 then
     ShowMessage('Object Not Found.');
 end;
 
 procedure TfMain.NMHTTP1Success(Cmd: CmdType);
 begin
   case Cmd of
     {Удостоверяемся, что процедура получения не была прервана}
     CmdGET:
       if NMHTTP1.Connected then
         lbMessages.Items.Append('Get Succeeded');
 
     CmdOPTIONS : lbMessages.Items.Append('Options Succeeded');
     CmdHEAD    : lbMessages.Items.Append('Head Succeeded');
     CmdPOST    : lbMessages.Items.Append('Post Succeeded');
     CmdPUT     : lbMessages.Items.Append('Put Succeeded');
     CmdPATCH   : lbMessages.Items.Append('Patch Succeeded');
     CmdCOPY    : lbMessages.Items.Append('Copy Succeeded');
     CmdMOVE    : lbMessages.Items.Append('Move Succeeded');
     CmdDELETE  : lbMessages.Items.Append('Delete Succeeded');
     CmdLINK    : lbMessages.Items.Append('Link Succeeded');
     CmdUNLINK  : lbMessages.Items.Append('UnLink Succeeded');
     CmdTRACE   : lbMessages.Items.Append('Trace Succeeded');
     CmdWRAPPED : lbMessages.Items.Append('Wrapped Succeeded');
   end;
 end;
 
 end.
 




<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ



Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS