На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Rouse_, jack128, Krid
  
    > Формулы передачи данных , для начинающих
      Формулы передачи данных для начинающих

      Автор: 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);

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

      ExpandedWrap disabled
        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.
      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script execution time: 0,0215 ]   [ 16 queries used ]   [ Generated: 2.05.24, 13:38 GMT ]