Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Интернет и сети
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 30.11.2012, 18:50
Snake22 Snake22 вне форума
Активный
 
Регистрация: 20.02.2011
Сообщения: 374
Репутация: 744
По умолчанию докачка в idhttpserver

Помогите сделать докачку при скачивании с idhttpserver.
у меня программа-сервак (idhttpserver) раздаёт файлы, и в случае обрыва скачивание начинается сначала.
сервер версии инди10

Последний раз редактировалось Snake22, 30.11.2012 в 18:53.
Ответить с цитированием
  #2  
Старый 30.11.2012, 19:56
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Правильно обрабатывать/выдавать заголовки Range/AcceptRange... Google и Wikipedia в помощь...
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #3  
Старый 30.11.2012, 20:09
Snake22 Snake22 вне форума
Активный
 
Регистрация: 20.02.2011
Сообщения: 374
Репутация: 744
По умолчанию

удалось нагуглить вот такой код.но в нём есть две строчки которые навероне изза инди10 не работают.
сторчки эти в конце кода,
первая:
FileStrm := TRangeFileStream(FileName,ARequestInfo.ContentRang eStart, ARequestInfo.ContentRangeEnd);
у меня почему-то можно передать только один параметр (FileName) а на остальные два пишет типа не требуются.
(Ошибка [Error] Unit1.pas(122): ')' expected but ',' found )
и вторая строчка,
AThread.Connection.WriteBuffer(LBuf, LNumRead);
в инди10 вместо Athread используется AContext и функции Connection.WriteBuffer нету тут.
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPServer, IdCustomHTTPServer,
  IdHTTPServer, StdCtrls,IdContext,math;



type
  TForm1 = class(TForm)
    IdHTTPServer1: TIdHTTPServer;
    Memo1: TMemo;
    Edit1: TEdit;
    procedure IdHTTPServer1CommandGet(AContext: TIdContext;
      ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

TRangeFileStream = class(TFileStream)
private
FRangeStart, FRangeEnd: Cardinal;
FRangeEnabled: Boolean;
function GetAbsolutePosition: Longint;
protected
property AbsolutePosition: Longint read GetAbsolutePosition;
public
constructor Create(const AFileName: String; ARangeStart, ARangeEnd:
Cardinal);
function Read(var Buffer; Count: Longint): Longint; override;
function Seek(Offset: Longint; Origin: Word): Longint; override;
property RangeStart: Cardinal read FRangeStart;
property RangeEnd: Cardinal read FRangeEnd;
end;

var
  Form1: TForm1;



implementation

{$R *.dfm}

constructor TRangeFileStream.Create(const AFileName: String;  ARangeStart, ARangeEnd: Cardinal);
var
LSize: Longint;
begin
inherited Create(AFileName, fmOpenRead or fmShareDenyWrite);
LSize := Self.Size;
if ARangeStart > LSize then begin
ARangeStart := LSize;
end;
if ARangeEnd > LSize then begin
ARangeEnd := LSize;
end;
FRangeEnabled := (ARangeStart <= ARangeEnd) and (ARangeEnd <> 0);
if FRangeEnabled then begin
FRangeStart := ARangeStart;
FRangeEnd := ARangeEnd;
end;
end;


function TRangeFileStream.GetAbsolutePosition: Longint;
begin
Result := inherited Seek(0, soFromCurrent);
end;

function TRangeFileStream.Read(var Buffer; Count: Longint): Longint;
var
LBytesLeft: Cardinal;
begin
if FRangeEnabled then begin
LBytesLeft := (FRangeEnd+1) - AbsolutePosition;
if Count > LBytesLeft then begin
Count := LBytesLeft;
end;
end;
Result := inherited Read(Buffer, Count);
end;

function TRangeFileStream.Seek(Offset: Longint; Origin: Word): Longint;
var
LPos: Longint;
begin
if FRangeEnabled then begin
Case Origin of
soFromBeginning: Offset := FRangeStart + Offset;
soFromCurrent: Offset := AbsolutePosition + Offset;
soFromEnd: Offset := (FRangeEnd+1) + Offset;
end;
Offset := Max(Offset, FRangeStart);
Offset := Min(Offset, FRangeEnd+1);
Origin := soFromBeginning;
end;
Result := inherited Seek(Offset, Origin);
end;
//============

procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);

var
FileStrm: TRangeFileStream;
LSize, LNumRead: Integer;
LBuf: array[0..1023] of Byte;
FileName:string;
begin
//...
FileStrm := TRangeFileStream(FileName,
ARequestInfo.ContentRangeStart, ARequestInfo.ContentRangeEnd); 
try
LSize := FileStrm.Size;

AResponseInfo.ContentType :='...'; //
AResponseInfo.ContentLength := LSize;
AResponseInfo.ContentRangeStart := FileStrm.RangeStart;
AResponseInfo.ContentRangeEnd := FileStrm.RangeEnd;
AResponseInfo.WriteHeader;

FileStrm.Position := 0;
while FileStrm.Position < LSize do
begin
LNumRead := FileStrm.Read(LBuf, Sizeof(LBuf));
if (LNumRead > 0) then begin
AThread.Connection.WriteBuffer(LBuf, LNumRead); 
end;
end;
finally
FileStrm.Free;
end;
end;

end.

Последний раз редактировалось Snake22, 30.11.2012 в 20:15.
Ответить с цитированием
  #4  
Старый 30.11.2012, 20:17
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

TRangeFileStream.Create
AResponseInfo.ContentStream
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #5  
Старый 30.11.2012, 20:19
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Вот тут ещё посмотреть можно: http://www.delphigroups.info/2/3b/184348.html
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #6  
Старый 30.11.2012, 20:45
Snake22 Snake22 вне форума
Активный
 
Регистрация: 20.02.2011
Сообщения: 374
Репутация: 744
По умолчанию

Ого,спасибо)
Такс,теперь надо разобраться. по ссылочке в принципе понятно о чём речь ,что в инди9 ошбика была и надо вручную строчку одну добавить в исходники idhttpserver'a, но,у меняж инди10 ,неужели там не исправили это?
и главное, что делать с
TRangeFileStream.Create
AResponseInfo.ContentStream
?
Ответить с цитированием
  #7  
Старый 30.11.2012, 20:50
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Первое - это решение первой ошибки. У тебя приведение типа
Код:
TRangeFileStream(Object);
А нужно создание объекта:
Код:
TRangeFileStream.Create(param1, param2, etc...);

Второе - это поток данных (TStream), используемый для отправки. Гугл в помощь, как говорится.
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #8  
Старый 30.11.2012, 21:01
Snake22 Snake22 вне форума
Активный
 
Регистрация: 20.02.2011
Сообщения: 374
Репутация: 744
По умолчанию

c первым разобрался,про второе непонятно.
там же,как я понял, циклом,до тех пор пока не дойдем до конца файла,передаём клиенту куски файла
Код:
while FileStrm.Position < LSize do
begin
LNumRead := FileStrm.Read(LBuf, Sizeof(LBuf));
if (LNumRead > 0) then begin
AThread.Connection.WriteBuffer(LBuf, LNumRead);
end;
а если я напишу
Код:
AResponseInfo.ContentStream:=TFileStream.Create('FileName',fmShareDenyNone);
то он начнёт весь файл сначала передавать,и получается опять что докачки не будет,и весь вышенаписанный код не нужен тогда
а если заменить
Код:
AThread.Connection.WriteBuffer(LBuf, LNumRead);
на
Код:
AResponseInfo.ContentStream.Write(LBuf, LNumRead);
то вылезает ошибка,кажется потому что поток вначале надо создать,а я незнаю как
Ответить с цитированием
  #9  
Старый 30.11.2012, 21:04
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Не-не, всё проще. TRangeFileStream.Create как раз создаёт поток, который содержит необходимые для передачи данные (только передаваемый кусок). Всё что надо - это присвоить этот поток параметру AResponseInfo.ContentStream, и задать правильные заголовки.
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #10  
Старый 30.11.2012, 21:38
Snake22 Snake22 вне форума
Активный
 
Регистрация: 20.02.2011
Сообщения: 374
Репутация: 744
По умолчанию

что то ничего не получается(((
AResponseInfo.ContentStream:=FileStrm
выдает ошибку при попытке скачать файл
Ответить с цитированием
  #11  
Старый 30.11.2012, 21:48
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Дежурный телепат форума в отпуске, так что вынужден спросить - "что за ошибка"?
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #12  
Старый 30.11.2012, 21:50
Snake22 Snake22 вне форума
Активный
 
Регистрация: 20.02.2011
Сообщения: 374
Репутация: 744
По умолчанию

ошибку Access violation error
словно AResponseInfo.ContentStream не создан а мы ему пытаемся присвоить
Ответить с цитированием
  #13  
Старый 30.11.2012, 21:52
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

В окне evaluate/modify посмотри, может сам AResponseInfo == nil.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #14  
Старый 30.11.2012, 21:58
Snake22 Snake22 вне форума
Активный
 
Регистрация: 20.02.2011
Сообщения: 374
Репутация: 744
По умолчанию

нет.там есть всякие значения.а вот
AResponseInfo.ContentStream равен nil
вот код если что
Код:
procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
FileStrm: TRangeFileStream;
LSize, LNumRead: Integer;
LBuf: array[0..1023] of Byte;

begin
//...
FileStrm := TRangeFileStream.Create(Edit1.Text,ARequestInfo.ContentRangeStart, ARequestInfo.ContentRangeEnd);

LSize := FileStrm.Size;

AResponseInfo.ContentType :='video/x-msvideo	avi';// для теста пока взял большой файл, фильмец
AResponseInfo.ContentLength := LSize;
AResponseInfo.ContentRangeStart := FileStrm.RangeStart;
AResponseInfo.ContentRangeEnd := FileStrm.RangeEnd;
AResponseInfo.WriteHeader;

FileStrm.Position := 0;

AResponseInfo.ContentStream:=FileStrm;


end;
Ответить с цитированием
  #15  
Старый 30.11.2012, 21:59
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Мэд, вряд ли, эти параметры не var, должны быть созданы до вызова.

Похоже, что косяк где-то в другом месте. Погуляй по коду трейсом в дебаге (бряк на начало процедуры и F8 до конца), и посмотри, на какой строчке валится AV.
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 08:33.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter