Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Загрузка файла из инета. (https://forum.antichat.xyz/showthread.php?t=159317)

Proger10 26.11.2009 17:26

Загрузка файла из инета.
 
Вопрос конечно не первый раз задается, но что нашел или не работает или еше что-нибудь. Ну так как сделать сабж, IdHTTP не предлагать!!

Nightmarе 26.11.2009 17:36

Код:

// Закачка файла на комп
function DownloadToComp(const fileURL, FileName: string): boolean;
const
  BufferSize = 1024;
var
  hSession, hURL: HInternet;
  Buffer: array[1..BufferSize] of Byte;
  BufferLen: DWORD;
  f: file;
begin
  Result := False;
  hSession := InternetOpen(nil, INTERNET_OPEN_TYPE_DIRECT, 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;

вызываешь так:
DownloadToComp('http://lol.ru/file.exe','C:\file.exe');
И не забудь в uses вписать APIшку WinInet

Ins3t 27.11.2009 00:35

2Nightmarе, не проще ли воспользоваться API функцией UrlDownloadToFile()

Nightmarе 27.11.2009 06:14

можно и так, но антивири будут ругаться на апишку urlmon.
вот подумай ©

Proger10 27.11.2009 15:45

2Ins3t, в моем случае не проще.
2Nightmarе, спасибо, то что надо!
А еше некто не поделится как проверить наличие возможности подключения к серверу по определенному порту(80)?? Желетельно через WinInet.

Nightmarе 27.11.2009 20:20

вот как раз через WinInet помоему и невозможно (хотя скорее всего нагло вру), ибо там функция проверки DialUp соединения, а если у юзверя через сетевую карту, то он активность всегда будет показывть онлайн.

Proger10 28.11.2009 10:55

Вот попытался сделать через winsAck:
Код:

procedure TForm1.Button1Click(Sender: TObject);
var
  WSAData: TWSAData;
  S: TSocket;
  SockAddrIn: TSockAddr;
  Timeout: TTimeVal;
begin
  if WSAStartup($101, WSAData)<>0 then
    exit;
  SockAddrIn.sin_family:=AF_INET;
  SockAddrIn.sin_addr.S_addr:=inet_addr(pchar(Edit1.Text));
  S:=socket(AF_INET,SOCK_STREAM,0);
  if S=INVALID_SOCKET then
    Exit;
  Timeout.tv_usec := 0;
  Timeout.tv_sec := 1000;
  setsockopt(S, SOL_SOCKET, SO_RCVTIMEO, @Timeout, sizeof(TTimeVal));
  SockAddrIn.sin_port:=htons(StrToInt(Edit2.Text));
  if connect(S, SockAddrIn, sizeof(SockAddrIn))=0 Then
  begin
    ShowMessage('Тут кто-то есть!');
  end
  else
  begin
    ShowMessage('Никого нет!');
  end;
end;

Если на порте кто-то есть, то все отлично программа вполне быстро сообщает об этом, а если там никого нет, то проходит секунд десять до соответствующего сообшения, попытался добаввить таймаут - нифига не получилось.. Что не так??

Proger10 29.11.2009 09:19

Где то прочитал что в Индюке эта проблема решается с помощю второго потока, сделал - вроде получилось.
Unit1:
Код:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, WinSock, ExtCtrls, Unit2;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    CanConnect: boolean;
    CanConnectChanged: boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  CanConnect:=False;
  Ping:= TPingThread.Create(True);
  Ping.IP:=Edit1.Text;
  Ping.Port:=StrToInt(Edit2.Text);
  Ping.Suspended:=False;
  for I := 1 to 1000 do
  begin
    Sleep(1);
    Application.ProcessMessages;
  end;
  if not CanConnectChanged then
  begin
    Ping.Suspended:=True;
    CanConnect:=False;
  end;
  if Canconnect then
    ShowMessage('We are TRUE!!')
  else
    ShowMessage('We are FALSE!!');
end;


end.

Unit2:
Код:

unit Unit2;

interface

uses
  Classes, WinSock;

type
  TPingThread = class(TThread)
    IP: string;
    Port: integer;
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

var
  Ping: TPingThread;

implementation

uses Unit1;

{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure TPingThread.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ TPingThread }

procedure TPingThread.Execute;
var
  WSAData: TWSAData;
  S: TSocket;
  SockAddrIn: TSockAddr;
begin
  if WSAStartup($101, WSAData)<>0 then
    exit;
  SockAddrIn.sin_family:=PF_INET;
  SockAddrIn.sin_addr.S_addr:=inet_addr(pchar(IP));
  S:=socket(AF_INET,SOCK_STREAM,0);
  if S=INVALID_SOCKET then
    Exit;
  SockAddrIn.sin_port:=htons(Port);
  if connect(S, SockAddrIn, sizeof(SockAddrIn))=0 Then
  begin
    Form1.CanConnectChanged:=True;
    Form1.CanConnect:=True;
  end
  else
  begin                         
    Form1.CanConnectChanged:=True;
    Form1.CanConnect:=False;
  end;
end;

end.

Низнаю правельно ли так делать!

Nightmarе 29.11.2009 13:32

Вот тебе правильный и рабочий код на индюке:

В uses добавляешь: IdMultipartFormData, IdHTTP
А далее функция:
Код:

function DownloadToComp(const fileURL, FileName: string):string;
var
postdownloadhttp:TidHTTP;
d:TIdMultiPartFormDataStream;
begin
postdownloadhttp:=TidHTTP.create(nil);
d:=TIdMultiPartFormDataStream.Create;
d.AddFile('userfile',FileName,'file');
try
postdownloadhttp.Post(fileURL+'?',d);
d.Free;
except
postdownloadhttp.Disconnect;
d.Free;
end;
postdownloadhttp.Free;
end;

работает по аналогии с вин инетом, только через пернатого.


Время: 01:47