![]() |
|
#1
|
|||
|
|||
![]() Всем доброго времени суток.
Задача следующая: скачать файл с сервера, который передается им просто-напросто открытым текстом. Упрощенно говоря, сервер дает его так: Код:
#perl here #$client - дескриптор клиента, IO::Socket open (IN, "<transfer.dat") or die; foreach (<IN>) { print $client $_; } close IN; close $client; Но это лирика, сервер гарантированно работает, проверялось клиентом на перле. Клиент должен этот файл корректно принять и записать на диск. Но есть одно но: нельзя использовать никаких компонентов, ни инди, ни прочих качалок, исключительно WinSock. Сам я, в течении уже третьего вечера пытаюсь реализовать сие дело таким образом: Код:
//delphi here Procedure net; var Outy : File of char; BigRecy : array[0..4196] of char; iRet : integer; begin // здесь идет реализация сокетов и прочая романтика, // к делу относящаяся лишь посредственно AssignFile (Outy, GetCurrentDir() + '\' + 'test.bin'); ReWrite(Outy); while (iRet<>0) do begin iRet := Recv(sServerListen, BigRecy, length(BigRecy), 0); if (iRet = 0) then break; BlockWrite(outy, BigRecy, 4196); end; close (Outy); end; Таким образам передавались разные типы файлов, от `man iptables`, то есть простого текста, до картинок и музыки. Результаты следующие: Начало и середина текста выглядели, вроде бы, адекватно, но конец иногда дублировался, иногда образался, всегда по-разному. Вместо невинной картинки приходила какая-то невнятная цветная мазня. С мп3 дело обстоит немного лучше, трек либо укорачивался, либо удлиннялся, с пробелами(которые плеер просто пропускал) примерно по 0.2 сек. Так как таким образом планируется передавать в основном исполняемые файлы, подобные баги-глюки-лаги абсолютно неприемлемы. Буду благодарен за комментарии по теме, особенно за рабочий код. |
#2
|
||||
|
||||
![]() Ставишь компонент TIdHTTP;
Код:
var ms : TMemoryStream; begin ms := TMemoryStream.Create; IdHTTP1.Get('<адрес файла в интернете>', ms); ms.SaveToFile('<имя файла>'); Кнопка "+" - весы в правом верхнем углу сообщения... |
#3
|
|||
|
|||
![]() Цитата:
уЧИСЬ ЧИТАТЬ |
#4
|
|||
|
|||
![]() раз речь идет о скачке, я немного спрошу по этому курсу?) только по поводу IdHTTP;
вот я качаю какой-либо файл... как определить его загрузку посредствои progressbar? не подскажите? ![]() |
#5
|
|||
|
|||
![]() используя idHTTP вроде никак, лучше winInet юзать
Delphi - это лишь инструмент, а что ты сможешь создать при помощи этого инструмента, зависит исключительно от тебя. |
#6
|
|||
|
|||
![]() ну хорошо, winInet.. отъюзал
![]() Код:
function GetInetFile(const fileURL, FileName: string): boolean; const BufferSize = 1024; var hSession, hURL: HInternet; Buffer: array[1..BufferSize] of Byte; BufferLen: DWORD; f: file; sAppName: string; begin Result := False; sAppName := ExtractFileName(Application.ExeName); hSession := InternetOpen(PChar(sAppName), INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); try hURL := InternetOpenURL(hSession, PChar(fileURL), nil, 0, 0, 0); try AssignFile(f, FileName); Rewrite(f,1); repeat InternetReadFile(hURL, @Buffer, SizeOf(Buffer), BufferLen); BlockWrite(f, Buffer, BufferLen); until BufferLen = 0; CloseFile(f); Result := True; finally InternetCloseHandle(hURL); end; finally InternetCloseHandle(hSession); end; end; Код:
var FileOnNet, LocalFileName: string; begin FileOnNet := Edit1.Text; LocalFileName := Edit2.Text; if GetInetFile(FileOnNet, LocalFileName) = True then ShowMessage('Загрузка завершена') else ShowMessage('Ошибка при закачке файла'); end; и ставим прогрессбар на панель: Код:
procedure TForm1.FormCreate(Sender: TObject); begin with ProgressBar1 do begin Parent := StatusBar1; Position := 0; Top := 2; Left := 0; Height := StatusBar1.Height - Top; Width := StatusBar1.Panels[0].Width - Left; end; end; осталось только отловить оставшееся время закачки ![]() |
#7
|
|||
|
|||
![]() если знаешь скорость и размер делим размер на скорость получаем время
Delphi - это лишь инструмент, а что ты сможешь создать при помощи этого инструмента, зависит исключительно от тебя. |
#8
|
|||
|
|||
![]() а если незнаю?
![]() |
#9
|
|||
|
|||
![]() раз у тебя есть прогресс бар значит знаешь
Delphi - это лишь инструмент, а что ты сможешь создать при помощи этого инструмента, зависит исключительно от тебя. |
#10
|
|||
|
|||
![]() нет, не знаю.. надо ведь сначала получить размер из файла, и скорость получить (это я подавно не знаю)... и в каком формате время выдасться?
|
#11
|
|||
|
|||
![]() у тебя буфер равен 1024 байтов 1 КБ воемя за которое он закачет 1 кб за секунду сколько он КБ закачает такова и скорость
Вот получение размера файла Код:
function THttpGet.getResourceSize(const AURL: String): Integer; var hOpen, hConnect, hResource: HINTERNET; host, resource: string; buflen, tmp: DWORD; begin hOpen := nil; hConnect := nil; hResource := nil; try ParseURL(AURL, host, resource); if not fError then begin hOpen := InternetOpen(fUserAgent, INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); CheckError; if not fError then hConnect := InternetConnect(hOpen, PChar(host), INTERNET_DEFAULT_HTTP_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 0); CheckError; if not fError then hResource := HttpOpenRequest(hConnect, 'HEAD', PChar(resource), nil, nil, nil, 0, 0); CheckError; if not fError then HttpSendRequest(hResource, nil, 0, nil, 0); CheckError; end; if not fError then begin buflen := SizeOf(Result); tmp := 0; Result := 0; HttpQueryInfo(hResource, HTTP_QUERY_CONTENT_LENGTH or HTTP_QUERY_FLAG_NUMBER, @Result, buflen, tmp); CheckError; end else Result := 0; InternetCloseHandle(hConnect); InternetCloseHandle(hOpen); except on E: Exception do ShowMessage(E.Message); end; end; Это я выдрал из своего класса, много у тебя нет, но основно смысл должен быть понять. Delphi - это лишь инструмент, а что ты сможешь создать при помощи этого инструмента, зависит исключительно от тебя. |
#12
|
|||
|
|||
![]() должен
![]() я впервые этот компонент увидел ![]() |
#13
|
|||
|
|||
![]() Цитата:
Попробуй определять размер последнего принимаемого блока. У тебя стоит размер 4196 для всех. А если размер завершающего, положим, 2000... Получим 2196 байт мусора... вот и появляется в конце файлов невесть что. Не пользовался приведёнными тобой функциями. Если функция Recv возвращает размер принятого блока(у тебя помещает длина блока в переменную iRet) то в строке BlockWrite(outy, BigRecy, 4196); замени цифру 4196 на переменную iRet. Т.е. BlockWrite(outy, BigRecy, iRet); Если нет, значит надо придумать как. Мысль я тебе дал. ![]() Последний раз редактировалось Амон, 17.11.2008 в 20:00. |
#14
|
|||
|
|||
![]() Цитата:
советую реализовать если это возможно и достаточно знаний на php ![]() |
#15
|
|||
|
|||
![]() Цитата:
TForm1.IdHTTP1Work(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer); Последний параметр - кол-во считанных байт. Инкрементный или за блок - не помню, попробуешь - определишь. Только придется в 2 этапа делать. Сначала получаешь размер ресурса, потом качаешь и вычисляешь %%. |