Integer Napisano Marzec 30, 2011 Zgłoś Share Napisano Marzec 30, 2011 Witam. Poniżej standardowa procedura do ściągania pliku, mam nadzieję że nie przestarzała Szukam informacji na temat jak ograniczyć prędkość ściągania a konkretnie idealne było by: 1. Jak sprawdzić prędkość pobierania z danego stanowiska np. SpeedNet=?B. 2. Jak zabezpieczyć się przed zawieszeniem w trakcje pobierania danych gdy internet padnie. 3. Na koniec jak ściągnąć plik z prędkością +-SpeedNet/10? Zastanawiałem się nad wątkami, ale manewrowanie priorytetami wątków nie jest na tyle precyzyjne, no i oczywiście jeśli dany wątek ściągający plik wisi to trzeba go umiejętnie kontrolować, a ja chciałem rozwiązać problem w zarodku ... o ile się da. //Procedura ściąga lub "dociąga" plik z internetu... function TNetFtp.SciagnijFile(Sender: TObject; adresURL, FNameZapisu :String): Boolean; // adresURL - zmienna z adresem URL z którego ściągamy plik // nazwaPliku - {nazwa pliku jaka ma być po ściągnięciu, może być dowolna var plik :File; inOpen, inURL :HINTERNET; HTTPRozmiarPliku, HTTPRozmiarPliku1 :DWORD; ileZnakow :DWord; dwBufLen, dwIndex :DWord; Sciagnieto, HDRozmiarPliku :DWord; bufor :array[1..1024] of byte; buf :Pointer; begin Result:= False; Stop:= false; //ustawiamy dane... inOpen:= nil; inURL:= nil; HDRozmiarPliku:= 0; HTTPRozmiarPliku:= 0; Sciagnieto:= 0; // ProgressBar1.Position:= 0; // jesli plik o takie j nazwie nie jest dostępny if ExistURL(adresURL) = False then begin Result:= False; Exit; end; //pobieramy rozmiar pliku jeżeli coś już ściągaliśmy... if FileExists(FNameZapisu) then begin AssignFile(plik, FNameZapisu); Reset(plik, 1); HDRozmiarPliku:= FileSize(plik); //pobieramy rozmiar pliku Seek(plik, FileSize(plik)); //ustawiamy skażnik na końcu pliku end else begin AssignFile(plik,FNameZapisu); ReWrite(plik, 1); end; Try //łączymy się z serwerem... //Label1.Caption:='Łączenie...'; // ------------------------------------ //Application.ProcessMessages; inOpen:= InternetOpen('Mozilla', PRE_CONFIG_INTERNET_ACCESS, nil, nil, 0); inURL:= InternetOpenURL (inOpen, PChar(adresURL), 'Accept: */*', StrLen('Accept: */*'),0 ,0 ); if not (inURL <> nil) then begin // ShowMessage('Nie można uzyskać połączenia'); // ------------------- Stop:= True; InternetCloseHandle(inURL); InternetCloseHandle(inOpen); CloseFile(plik); Exit; end; //pobieramy całkowity rozmiar pliku znajdującego sie na serwerze... dwIndex:= 0; dwBufLen:= 1024; GetMem(Buf, dwBufLen); HttpQueryInfo(inURL, HTTP_QUERY_CONTENT_LENGTH, buf, dwBufLen, dwIndex); //ustawiamy progresy (paski postępu) HTTPRozmiarPliku1:= StrToInt(StrPas(Buf)); HTTPRozmiarPliku := HTTPRozmiarPliku1; //Caption:= 'Rozmiar pliku do ściągnięcia: '+ IntToStr(rozmiar); // ProgressBar1.Max:= rozmiar; // ProgressBar1.Position:= rozmiarPliku; { ustawiamy wskażnik pliku znajdującego się na serwerze, czyli ustalamy od jakiego miejsca w pliku rozpoczynamy pobieranie } if HDRozmiarPliku > 0 then InternetSetFilePointer(inURL, HDRozmiarPliku, nil, 0, 0); //pobieranie pliku z serwera... //Label1.Caption:='Ściąganie pliku...'; // ------------------------------- while (ileZnakow <> 0) and (Stop = false) do begin InternetReadFile(inURL, @bufor, SizeOf (bufor), ileZnakow); InternetQueryDataAvailable(inURL, HTTPRozmiarPliku, 0, 0); BlockWrite(plik, bufor, ileZnakow); Sciagnieto:= FileSize(plik); // Label2.Caption:='Ściągnięto '+ IntToStr(sciagnieto); // ------------ // ProgressBar1.Position:= sciagnieto; // Application.ProcessMessages; end; except //ShowMessage('Wystąpił błąd podczas ściągania pliku !'); Stop:= True; InternetCloseHandle(inURL); InternetCloseHandle(inOpen); CloseFile(plik); Exit; end; Stop:= False; InternetCloseHandle(inURL); InternetCloseHandle(inOpen); CloseFile(plik); if (HDRozmiarPliku = HTTPRozmiarPliku1) or (Sciagnieto = HTTPRozmiarPliku1) then Result:= True else Result:= False; { if ProgressBar1.Position = ProgressBar1.Max then // Label1.Caption:= 'Plik został ściągnięty' // ----------------------- else Label1.Caption:= 'Zatrzymane ściąganie pliku'; } //Beep; end; Link do komentarza Udostępnij na innych stronach More sharing options...
Blind Napisano Marzec 30, 2011 Zgłoś Share Napisano Marzec 30, 2011 Jak chcesz ograniczyć prędkość pobierania to poprostuj odczytuj tylko tyle danych ile chcesz w danej jednostce czasu np. chcesz predkosc 1kb/s to stwórz bufor o takiej wielkości i nie pobieraj nowej paczki częsciej niż co 1s. Co do sprawdzania pedkości pobierania to prawie to samo co wyżej tylko że sprawdzasz jaki upłynął czas przy ściąganiu paczki. W jaki sposób zabezpieczyć? Jak coś będzie nie tak z połączeniem to pewnie dostaniesz Exceptiona. Najprościej wywalić co się wszystko ściągneło i zacząć od nowa. Tylko niektóre serwery pozwalają na ściąganie od dowolnego miejsca, ale nie wiem jak to się robi pewnie ustala się to w nagłówku HTTP. Jeśli nie zrobisz tego na wątkach to aplikacja ci się zawiesi na czas pobierania pliku a to złe jest. Przy ściąganiu pojednynczych plików można zaprojektować wątek tak, że obejdzie się bez synchronizacji z innymi wątkami, reszta jest już prosta. www.blinder.pl - Blog Link do komentarza Udostępnij na innych stronach More sharing options...
Integer Napisano Marzec 31, 2011 Autor Zgłoś Share Napisano Marzec 31, 2011 Czyli tak czy owak najbezpieczniejsze są wątki . dzięki Link do komentarza Udostępnij na innych stronach More sharing options...
Polecane posty
Zarchiwizowany
Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.