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

Автор: Jason Pierce
Данным примером я попытаюсь дать ответы на следующие вопросы:
Каково различие между 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.

Взято из http://forum.sources.ru

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...