views:

439

answers:

3

i coded this program to upload a file on server using ftpput api it is not working it runs but file is not delevered!

here's the code:

unit ftp3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,wininet;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

    {$R *.dfm}

    procedure TForm1.Button1Click(Sender: TObject);

       var hInet, hConnect: HINTERNET; 

    local_file, 
    remote_file,
    user,remote_server,
    pass: pchar;

    begin 
    local_file := 'C:\Documents and Settings\Omair\Desktop\loggen.txt';
    remote_file := 'loggen.txt';
    user := 'my user';
    pass := 'my pass';
    remote_server := ' ftp.drivehq.com';

    hInet := InternetOpen(0, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
    hConnect := InternetConnect(hInet,
        remote_server, 
        INTERNET_DEFAULT_FTP_PORT,
        user, pass,
        INTERNET_SERVICE_FTP,
        INTERNET_FLAG_PASSIVE,
        0);

    ftpPutFile(hConnect, local_file, remote_file, FTP_TRANSFER_TYPE_BINARY, 0);

    InternetCloseHandle(hInet);
    InternetCloseHandle(hConnect);

    end;   

  end.
+4  A: 

Check return value of FtpPutFile (it should return TRUE on success) and get a detailed error with GetLastError.

pingw33n
+4  A: 

And why don't you try a little harder to see what's going on by testing all the return codes to be sure of where it fails?

procedure TForm1.Button1Click(Sender: TObject);
var
  hInet, hConnect: HINTERNET;
  local_file, remote_file, user,remote_server, pass: PChar;
begin
  local_file := 'C:\Documents and Settings\Omair\Desktop\loggen.txt';
  remote_file := 'loggen.txt';
  user := 'my user';
  pass := 'my pass';
  remote_server := ' ftp.drivehq.com';

  hInet := InternetOpen(0, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
  if hInet = nil then
    RaiseLastOSError;

  hConnect := InternetConnect(hInet,
    remote_server,
    INTERNET_DEFAULT_FTP_PORT,
    user, pass,
    INTERNET_SERVICE_FTP,
    INTERNET_FLAG_PASSIVE,
    0);
  if hConnect = nil then
    RaiseLastOSError;

  if not ftpPutFile(hConnect, local_file, remote_file, FTP_TRANSFER_TYPE_BINARY, 0) then
    RaiseLastOSError;

  if not InternetCloseHandle(hConnect) then
    RaiseLastOSError;
  if not InternetCloseHandle(hInet) then
    RaiseLastOSError;
end;

You don't even know if you got the connection before trying to send the file... (It's what I got, as expected, when running the code with these site/user/password values)

And if you get past that, you may actually get a detailed explanation as to why ftpPutFile fails, like in this example:

System Error.  Code: 3.

The system cannot find the path specified.
François
it returns error code 12002 on ' if not ftpPutFile(hConnect, local_file, remote_file, FTP_TRANSFER_TYPE_BINARY, 0) then RaiseLastOSError;' linei googled this error code it means "The request has timed out." and "ERROR_INTERNET_TIMEOUT" please help!!!!and sorry i forgot to mention i am new to programming
Omair Iqbal
@Omair - if you're getting time-out errors, try the approach listed in my answer to check that your system and the FTP site can actually exchange information first - the problem might not be in your code as such [though you should write code to handle these sort of errors properly. :-)]
robsoft
+2  A: 

First of all, rule-out any major errors in your program (or rule them in, if you like) by checking you can FTP that same file with Microsoft's built-in FTP program.

From the command line, type

FTP ftp.drivehq.com (return)

if this doesn't come back to you with a login prompt, you have problems outside of your Delphi code. Either you have limited internet connectivity (maybe port 25, the FTP port, is blocked by your firewall/router) or there is a problem with the FTP address itself.

If you do get a prompt, enter your username and password when asked. Now type

BIN (return)
PUT 'C:\Documents and Settings\Omair\Desktop\loggen.txt' (return)

if that seems to send your file, (type BYE to leave the FTP program, by the way) then your problem is with your Delphi code rather than with the FTP process itself (the other answers here have helpfully pointed out things you need to check in the Delphi code itself). If it doesn't seem to send the file, again I suggest you look to resolving that problem before you carve-up your Delphi code.

 

When I'm doing any kind of 'online' work like this, I always try to get a separate process for testing the 'other end' of the system, one that doesn't use any of my own code.

robsoft
i tried put C:\Documents and Settings\Omair\Desktop\loggen.txt as well as put C:\Documents and Settings\Omair\Desktop\loggen.txt [/loggen.txt]using microsft comand line ftp it failed!! does that mean something wrong with my windows ftpalso i was once tweaking my delphi code over and over again and it accidently uploaded it i dont remember what i did that uploaded it as i was experimenting very frequently
Omair Iqbal
Copy the file to the root of the C:\ drive, make sure it's read-only attribute is not set, start a command prompt, cd to the root of your c:\ drive and FTP from there. delete any existing loggen.txt from the FTP server ('del loggen.txt' I think, no Windows machine handy at the moment!). You won't need any filepath in the filename, because you're going from the root where the file is, so just use loggen.txt as the filename. Now, see what happens...? Good luck!
robsoft
hey my code is working now thank you!it seems like my mistake was i was using a blank space ie ' ftp.drivehq.com' instead of 'ftp.drivehq.com' i cant beleave i made such an obvious mistake!
Omair Iqbal
one more question : are there any advantages in term of performance when using direct api function like ftpputfile above? i mean if i use a component,indy,synapce library etc would that make my code slower?
Omair Iqbal
Omair - there's no huge advantage in my experience. The things you get from those components will be a nice degree of error-trapping and state-handling, options like encryption and secure connections - all good things, and often worthy of inclusion (especially if you're building something commercial). But if all you're trying to do is get a file from A to B and you're not scared-off by the WinInet API then I'd just use it as-is. I have to say, from some of your other comments and points above, you might be better served using an FTP component that will trap and fire off 'error' events for you.
robsoft
you say 'there is no huge advantage' but is there advantage still? even if its just 2-4%and which component do u recommend?
Omair Iqbal
Sory Omair, I've no idea how to turn a list of useful features into a 'percentage' - that's bizarre! If you are building an end-user, commercial tool (or if you might need things like secure, encrypted connections), then I'd get a third party component and save time/frustration/testing. If you're just building an internal tool with no outside market then I'd just use the APIs. I can't honestly recommend a component because I have limited experience of 'SecureBlackBox' and no experience of anything else (I almost always just hit the WinInet API). Maybe raise a new question, for FTP components?
robsoft
sorry i didnt clarify my question what i meant to say was is there any advantage in using ''api'' instead of components in terms of performance, like they say assembly code runs faster than say c++ my question is does direct api(like wininet) runs faster than third party components?thanks again for help and patience :)
Omair Iqbal
Cool, I understand now. :-) I don't think there would be any real performance advantage in using the direct api over a 3rd party component, unless the component had a particularly over-complex design, or a large number of associated events. The real performance hit in FTP is likely to be the actual network transfer and so you might look at the transfer blocksize inside your transfer loop, and also how you're reading/writing the files to/from the disk. Other than that, I'd pick a component if you need extra features/want to save time, stick to API if you don't mind the work/want to save money!
robsoft