Background Intelligent Transfer Service

From EIK wiki

Intelligentne taustaülekande teenus (Background Intelligent Transfer Service – BITS) on modernse Microsoft Windows operatsioonisüsteemi komponent, mis hõlbustab failide ülekannet kasutades vaba võrgu ribalaiust. See on kõige levinumalt kasutatud viimastel Windows Update, Microsoft Update, Windows Server Update Services ja Systems Management Server versioonidel. BITS aitab üle kanda tarkvarauuendusi klientidele, selle abil saab Microsofti viirusevastane skänner Microsoft Security Essentials tõmmata vajalikke uuendusi ning samuti kasutatakse seda tehnoloogiat ka Microsofti sõnumside toodetel failide ülekandmiseks. Erinevalt teistest protokollidest, mis kannavad faile üle esiplaanil, BITS kannab neid üle tagataustal. Tagatausta ülekanded uurivad võrguliiklust ning kasutavad ainult vaba võrgu ribalaiust, et mitte takistada kasutajal võrgurakenduste (näiteks Internet Explorer) kasutamist. BITS muudab oma ribalaiust olenevalt kasutaja tegevusest.


Tehnoloogia

Töö

BITS sessioon algab töö loomisest. Töö on konteiner, mis sisaldab ühte või mitut edastatavat faili. Äsjaloodud töö ei sisalda ühtegi faili, need peab sinna lisama kindlaks määrates nii allika kui sihtkoha URI. Allalaadimise töö võib sisaldada ükskõik mitu faili, kuid üleslaadimise töö ainult ühte. Atribuute võib määrata iga individuaalse faili kohta. BITS pakub rakendusliidest, et tööd kontrollida. Tööd võib programmiliselt alustada, peatada, lõpetada, taastada. Enne töö alustamist, tuleb määrate selle prioriteet, et BITS teaks, mis järjekorras olemasolevaid töid ette võtta. On olemas mitu prioriteedi astet (Normal, High, Low, Foreground). BITS optimeerib taustaülekandeid olenevalt sellest kui palju vaba võrgu ribalaiust on saadaval. Kui võrgurakendus hakkab kasutama rohkem ribalaiust, BITS vähendab enda edastuskiirust, et mitte häirida kasutajal võrgurakenduste kasutamist. Nii toimib see alati, v.a esiplaani edastuse puhul. Esiplaani edastused võistlevad võrgu ribalaiuse pärast teiste rakendustega.

Creating job.png
Joonis 1: Töö loomine

Töö staatus

Iga töö sisaldab oleku ja progressi informatsiooni, mida saab kasutada töö staatuse määramisel. Olekus on öeldud, kas töö on järjekorras, edastab faile või viibib veaseisundis. Töö progressi informatsioon näitab kui palju faile või baite on edastatud. Infot progressi kohta võib saada nii kogu töö kui eraldi mõne faili kohta.

On olemas võimalus määrata teateid teatud sündmuste kohta:

• JobTransferred: Kõik töös olevad failed on edastatud. Töö on edastatud olekus.
• JobError: On toimunud viga. Töö on veaseisundis.
• JobModification: Tööd on modifitseeritud.

Aja planeerimine

BITS planeerib iga tööd nii, et töö saab ainult teatud ajaperioodi, mille jooksul edastatakse ainult teda. Enne seda on töö ajutiselt peatatud, et anda teisele tööle võimaluse ennast edastada. Kõrgema prioriteediga tööd saavad enda edastamiseks rohkem aega. Sama prioriteediga tööde puhul kasutab BITS round-robin ressursijaotuse algoritme.
Äsjaloodud töö on automaatselt peatatud, seega on vajalik ta uuesti käivitada. Uuesti käivitamisel liigub töö järjekorda. Kui saabub andmete edastamise aeg ühendub töö kõigepealt kaugserveriga ning siis alustab edastamist. Kui tööle eraldatud aeg saab läbi, on edastus ajutiselt peatatud ning töö liigub taas järjekorda. Kui on uuesti selle töö kord edastamiseks, peab see enne edastamist uuesti ühenduma. Kui töö on lõpule viidud, BITS edastab töö omandiõiguse selle töö loonud rakendusele. BITS sisaldab sisseehitatud mehhanismi vigadega tegelemise ja taastamise katsete jaoks. Viga võib olla kas lõplik või mööduv. Mööduv viga on ajutine ning lahendab ennast mõne aja jooksul ise. Lõpliku vea puhul pöördub BITS töö loonud rakenduse poole üritades edasi anda võimalikult palju informatsiooni vea kohta.

Kasutaja ja võrguühendus

BITS edastab faile ainult siis kui töö omanik on sisse loginud ning on olemas võrguühendus. Omanikuks on kasutaja, kes on töö loonud ning ainult temal on õigus tööd muuta. Kasutaja, kellel on administraatori õigused, võib muuta iga tööd ning samuti üle võtta töö omandiõiguseid. BITS peatab töö, kui omanik logib välja või võrguühendus katkeb ning taastab töö kui omanik logib uuesti sisse ja võrguühendus taastub. BITSi võib kasutada ka failide edastamiseks teenustelt. Teenused peavad töötama LocalSystem, LocalService või NetworkService süsteemikontode all. Süsteemikontosid peetakse alati sisseloginuks, nii et nende poolt alustatud edastused töötavad pidevalt (st. kuni arvuti töötab ning on olemas võrguühendus).

Tööriistad

BitsAdmin
BitsAdmin on käsurea tööriist, mis haldab enamikku BITS töödest. See on saadaval koos Windows XP Service Pack 2 Support Tools või Windows Server 2003 Service Pack 1 Support Tools ning mõlema uuemate versioonidega. Samuti on see sandartne käsurea tööriist Windows Vistas ja hilisemates versioonides.

BITS ja teised tehnoloogiad

Tehno vordlus.png

BITS installeerimine


Vajuta Start (Start), Haldustööriistad (Administrative Tools), Serveri haldaja (Server Manager).

Bits.png

Vajuta Funktsioonid (Features), Lisa funktsioonid (Add Features).

Bits2.png

Vali Background Intelligent Transfer Service (BITS)

Bits3.png

Vajuta Lisa nõutavad rolliteenused (Add Required Role Services).

Bits4.png

Vajuta Edasi (Next), Installeeri (Install) ning kui installeerimine on lõppenud Sulge (Close).

Bits5.png

Bits6.png

Bits7.png

Bits8.png

Bits9.png

Bits10.png

BITS kasutamine

Ühendamine BITS teenusega

Selleks, et ühendada BITS teenus, peab loomad BackgroundCopyManager objekti, nagu on näidatud järgnevas näites:


#define UNICODE
#define _WIN32_WINNT  0x0500
#include <windows.h>
#include "bits.h"

//Global variable that several of the code examples in this document reference.
IBackgroundCopyManager* g_pbcm = NULL;  
HRESULT hr;

//Specify the appropriate COM threading model for your application.
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr))
{
  hr = CoCreateInstance(__uuidof(BackgroundCopyManager), NULL,
                        CLSCTX_LOCAL_SERVER,
                        __uuidof(IBackgroundCopyManager),
                        (void**) &g_pbcm);
  if (SUCCEEDED(hr))
  {
    //Use g_pbcm to create, enumerate, or retrieve jobs from the queue.
  }

Ülekande töö loomine

BITS töö loomise näide:

HRESULT hr;
GUID JobId;
IBackgroundCopyJob* pJob = NULL;
//To create an upload job, replace BG_JOB_TYPE_DOWNLOAD with 
//BG_JOB_TYPE_UPLOAD or BG_JOB_TYPE_UPLOAD_REPLY.
hr = g_pbcm->CreateJob(L"MyJobName", BG_JOB_TYPE_DOWNLOAD, &JobId, &pJob);
if (SUCCEEDED(hr))
{
//Save the JobId for later reference. 
//Modify the job's property values.
//Add files to the job.
//Activate (resume) the job in the transfer queue.
}
 }

Failide lisamine

Ühe faili lisamise näide:

HRESULT hr;
IBackgroundCopyJob* pJob;
 //Replace parameters with variables that contain valid paths.
hr = pJob->AddFile(L"http://ServerName/Path/File.Ext", L"d:\\Path\\File.Ext");
if (SUCCEEDED(hr))
{
 //Do something.
}

  Mitme faili lisamise näide:

 HRESULT hr;
 IBackgroundCopyJob* pJob;
 BG_FILE_INFO* paFiles = NULL;
 ULONG idx = 0;
 ULONG nCount = 0;            //Set to the number of files to add to the job.
 LPWSTR pszLocalName = NULL;  //Comes from the list in the user interface.
 LPWSTR pszRemoteName = NULL; //Comes from the list in the user interface.
 //Set nCount to the number of files to transfer.
//Allocate a block of memory to contain the array of BG_FILE_INFO structures.
 //The BG_FILE_INFO structure contains the local and remote names of the 
 //file being transferred.
 paFiles = (BG_FILE_INFO*) malloc(sizeof(BG_FILE_INFO) * nCount);
 if (NULL == paFiles)
 {
  //Handle error
 }
 else
 {
   //Add local and remote file name pairs to the memory block. 
   for (idx=0; idx<nCount; idx++)
   {
     //Set pszLocalName to point to an LPWSTR that contains the local name or
     //allocate memory for pszLocalName and copy the local name to pszLocalName.
     (paFiles+idx)->LocalName = pszLocalName;
     //Set pszRemoteName to point to an LPWSTR that contains the remote name or
     //allocate memory for pszRemoteName and copy the remote name to pszRemoteName.
     (paFiles+idx)->RemoteName = pszRemoteName;
   }
   //Add the files to the job.
   hr = pJob->AddFileSet(nCount, paFiles);
   if (SUCCEEDED(hr))
   {
      //Do Something.
   }
   //Free the memory block for the array of BG_FILE_INFO structures. If you allocated
   //memory for the local and remote file names, loop through the array and free the
   //memory for the file names before you free paFiles.
   free(paFiles);
 }

BITS töö käivitamine

Uue töö aktiveerimine või peatatud töö taaskäivitamine:

HRESULT Resume();

Tagastatav väärtus:

S_OK: Töö on edukalt (taas)käivitatud
BG_E_EMPTY: Puuduvad failid ülekandmiseks
BG_E_INVALID_STATE: Töö staatus ei võimalda seda (taas)käivitada

BITS failide ülekannete kontroll

Järgnev näide kasutab töö staatuse määramiseks taimerit:

HRESULT hr;
IBackgroundCopyJob* pJob;
BG_JOB_STATE State;
HANDLE hTimer = NULL;
LARGE_INTEGER liDueTime;
//IBackgroundCopyError* pError = NULL;
//BG_JOB_PROGRESS Progress;
//WCHAR *JobStates[] = { L"Queued", L"Connecting", L"Transferring",
//                       L"Suspended", L"Error", L"Transient Error",
//                       L"Transferred", L"Acknowledged", L"Canceled"
//                     };
liDueTime.QuadPart = -10000000;  //Poll every 1 second
hTimer = CreateWaitableTimer(NULL, FALSE, L"MyTimer");
SetWaitableTimer(hTimer, &liDueTime, 1000, NULL, NULL, 0);
do
 {
  WaitForSingleObject(hTimer, INFINITE);
 //Use JobStates[State] to set the window text in a user interface.
  hr = pJob->GetState(&State);
  if (FAILED(hr))
  {
    //Handle error
  }
  if (BG_JOB_STATE_TRANSFERRED == State)
    //Call pJob->Complete(); to acknowledge that the transfer is complete
    //and make the file available to the client.
  else if (BG_JOB_STATE_ERROR == State || BG_JOB_STATE_TRANSIENT_ERROR == State)
    //Call pJob->GetError(&pError); to retrieve an IBackgroundCopyError interface 
    //pointer which you use to determine the cause of the error.
  else if (BG_JOB_STATE_TRANSFERRING == State)
    //Call pJob->GetProgress(&Progress); to determine the number of bytes 
    //and files transferred.
} while (BG_JOB_STATE_TRANSFERRED != State && 
         BG_JOB_STATE_ERROR != State &&
         BG_JOB_STATE_TRANSIENT_ERROR != State);
CancelWaitableTimer(hTimer);
CloseHandle(hTimer);

Näide teadete registreerimise kohta:

HRESULT hr;
IBackgroundCopyJob* pJob;
CNotifyInterface *pNotify = new CNotifyInterface();
if (pNotify)
{
    hr = pJob->SetNotifyInterface(pNotify);
    if (SUCCEEDED(hr))
    {
        hr = pJob->SetNotifyFlags(BG_NOTIFY_JOB_TRANSFERRED | 
                                  BG_NOTIFY_JOB_ERROR );
    }
    pNotify->Release();
    pNotify = NULL;
 if (FAILED(hr))
    {
        //Handle error - unable to register callbacks.
    }
}
 

Näide teadete määramisest sündmustepõhiselt:

#define MAX_PARAMETER_LEN 4000

HRESULT hr;
IBackgroundCopyJob* pJob;
IBackgroundCopyJob2* pJob2 = NULL;
WCHAR szJobId[48];
WCHAR *pProgram = L"c:\\PATHHERE\\PROGRAMNAMEHERE.exe";
WCHAR szParameters[MAX_PARAMETER_LEN+1];
GUID JobId;
int rc;
hr = pJob->GetId(&JobId);
if (SUCCEEDED(hr)
{
  rc = StringFromGUID2(JobId, szJobId, sizeof(szJobId));
  if (rc)
  {
    StringCchPrintf(szParameters, MAX_PARAMETER_LEN+1, L"%s %s", pProgram, szJobId);
    pJob->QueryInterface(__uuidof(IBackgroundCopyJob2), (void**)&pJob2);
    hr = pJob2->SetNotifyCmdLine(pProgram, szParameters);
    if (SUCCEEDED(hr))
    {
      hr = pJob->SetNotifyFlags(BG_NOTIFY_JOB_TRANSFERRED);
    }
    pJob2->Release();
    if (FAILED(hr)
    {
      //Handle error - unable to register for command line notification.
    }
  }
}

Kasutatud kirjandus

Autor

Inger Romanenko A21