아래화일은 화일전송프로그램입니다.
아래것은 서버에 있는것을 가지고 올수만있더군요..
이것을 어떤방법을 서버로 전송도 가능하게 만들수 있을까요.
참고로 이 소스는 인터넷 서핑해서 찾은겁니다...아마 한델인것 같은데.
도움 바랍니다.
unit FTPGetFile;
interface
uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, StdCtrls, Dialogs, Buttons, ComCtrls, ExtCtrls, Winsock;
type
  // FTP control에서 사용될 상수
  // 비동기적으로 호출되는 Command_Proc에서 현재 작업의 상태를 알기위해
  TCommand = (PUT_USER, PUT_PASS, PUT_CWD,  PUT_QUIT, PUT_TYPE, PUT_RETR,
              PUT_STOR, PUT_DELE, PUT_RMD,  PUT_MKD,  PUT_LIST, PUT_NLST,
              PUT_HELP, PUT_PORT, PUT_PWD,  PUT_SYST, PUT_ACCT, GET_MESSAGE,
              CHK_REST, PRX_OPEN1, PRX_SITE1, PRX_SITE2, PRX_SITE3);
const
  // 함수에서 사용할 네트워크 메시지
  WM_CONNECT_MSG = WM_USER + 100; // 호스트의 포트에 연결시 발생되는 원도우즈 메시지
  // (주의) 이 프로그램의 비동기 통신방법
  // 1. connect() : WSAAsyncSelect() 함수 사용
  // 2. accept(), recv(), send() : select() 함수 사용
  // 3. 호스트 이름 resolve : WSAAsyncGetHostByName(), WSAAsyncGetHostByAddr() 함수 사용
type
  TFTPGetForm = class(TForm)
    BB_Stop: TBitBtn;
    Label2: TLabel;
    L_Rfile: TLabel;
    Label5: TLabel;
    L_Rsize: TLabel;
    Label3: TLabel;
    ProgressBar1: TProgressBar;
    CB_Message: TComboBox;
    Panel1: TPanel;
    Timer1: TTimer;
    L_Speed: TLabel;
    Image_update: TImage;
    Image_new: TImage;
    procedure FormActivate(Sender: TObject);
    procedure BB_StopClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    { Private declarations }
    {Message Handler}
    procedure ConnectMessage(var Msg: TMessage); message WM_CONNECT_MSG;
    {FTP부분에 사용되는 기본 method}
    function  Send_Command(cStr: String): Boolean;
    procedure AllCloseSocket;
    function  GetFTPListenSocket: Tsocket;
    procedure DOclosesocket(var socket_id: Tsocket);
    procedure DOAddLine(str: String);
    function  GetReply: Boolean;
    procedure Process_ReplyMessage;
    procedure asyncselect(synsocket: Tsocket; readsock: Boolean);
    procedure asyncconnect(synsocket: Tsocket; synsocket_in: TSockAddrIn; trytimes: Integer);
    function  AbortCom: Boolean;
    function  Get_Value(Str, cSpr:String; nPos: Integer): String;
  public
    { Public declarations }
    HOST_IP        : String;  {호스트 IP}
    USER_ID        : String;  {사용자 ID}
    PASSWORD       : String;  {비밀번호}
    PASSIVE_MODE   : Boolean; {passive mode}
    SEND_FILENAME, RECV_FILENAME, TRAN_MODE: String;
    FTPTransfered  : Boolean; {전송완료 여부}
    {WSAGetLastError함수에 의해 리턴된 에러번호에 해당하는 메시지를 구한다}
//    function GetWinsockError(error: Integer):String;
    function FTP_connect: Boolean;
    function Send_HostFile(SendFile, RecvFile: String; BinFile: Boolean): Boolean;
  end;
const
  SEND_BYTE         = (4096 - 1);     {전송 버퍼의 크기}
  RECV_BYTE         = (4096 - 1);     {수신 버퍼의 크기}
  SERVER_PORT       = 21; {FTP port}
  ASYNC_TIMEOUT_SEC = 60; {default timeout}
  TRANS_STEPBY      = 5;  {transfer step}
  
{ Macro = 'Indicate code'  (FTP 서버의 respond message) }
  C150  = '150'; {Opening data connection for xxxxxxxx.xxxx}
  C200  = '200'; {일반명령어의 실행 성공}
  C213  = '213'; {Fise Size}
  C220  = '220'; {Service ready}
  C226  = '226'; {Transfer complete}
  C227  = '227'; {Entering Passive Mode (130,33,2,28,4,62)}
  C250  = '250'; {DELE or RMD or CWD command successful}
  C331  = '331'; {Password required for xxxx} {331 Anonymous access allowed, send identity (e-mail name) as password}
  C230  = '230'; {User xxxx logged in}
  C257  = '257'; {"xxxxxx" is current directory} {MKD command successful}
  C350  = '350'; {File exists,ready for destination name}
  C500  = '500'; {command not understood.}
  C502  = '502'; {REST command not implemented.}
  C530  = '530'; {Login incorrect}
  C550  = '550'; {"xxxxxx": Permission denied.}
  C553  = '553'; {"xxxxxx": Permission denied or Cannot rename to /c:/insa/bin/aaa/WHATSNEW.TXT}
var
  FTPGetForm: TFTPGetForm;
  ctrl_skt,  Listen_skt, Data_skt: Tsocket;
  Server_in, Local_In, Listen_in, Data_in: TSockAddrIn;
  ReplyMsg   : String;   {reply message}
  SendBuff   : array[0..SEND_BYTE] of Char; {명령어 전송용 버퍼}
  RecvBuff   : array[0..RECV_BYTE] of Char; {메시지(응답) 수신용 버퍼}
  Comd       : TCommand;
  RecvFileSize: LongInt;
  trans_time, trans_bps: Real;
  // select() 함수에서 사용하는 변수
  Start_Time: Longint;
  readfds, writefds: TFDSet;
  readycomm: Integer;
  timeval: TTimeVal;
implementation
{$R *.DFM}
function TFTPGetForm.FTP_connect: Boolean;
var
  Address: DWord;     // 이진의 네트워크 IP주소(4 bytes)
  i: Integer;
begin
  Result := False;
  DOAddLine('Connecting to '+HOST_IP+'  port '+IntToStr(SERVER_PORT));
  // 인터넷의 IP주소를 의미하는 문자열은 네 개의 숫자와 그들을 구분하는 도트(".')
  // 로 구성된다. 그래서 inet_addr은 그 문자열에 해당하는 네트워크 바이트 순서로
  // 된 이진의 IP주소를 리턴한다(4 bytes).
  Address := inet_addr(PChar(HOST_IP));
  // inet_addr은 인자로 전달된 도트 표현의 IP주소에서 4개의 숫자 가운데
  // 255를 넘는 값이 있다거나 기타 이유로 이진 IP주소로 변환될 수 없는
  // 문제가 있는 문자열인 경우 INADDR_NONE 값을 리턴한다.
  if Address = INADDR_NONE then
  begin
    DOAddLine('Connection failed '+HOST_IP);
    DOAddLine('호스트를 알 수 없습니다.  호스트 주소를 확인하세요.');
    System.Exit;
  end;
  // 서버연결을 위한 상대방의 주소 지정
  with Server_in do
  begin
    FillChar(Server_in, SizeOf(Server_in), #0);
    sin_family          := PF_INET; // 주소 영역은 현재 PF_INET 뿐이다
    sin_addr.s_addr     := Address; // 이진의 IP주소(네트워크 바이트 순서의 4 bytes)
    sin_port            := htons(SERVER_PORT); // 네트워크 바이트 순서의 FTP port 번호(well-known port numer)
  end;
  {Control Connection port 21(ftpd)}
  ctrl_skt := INVALID_SOCKET;
  ctrl_skt := socket(PF_INET, SOCK_STREAM, 0); // PF_INET 주소 영역의 TCP 프로토콜을 사용
  if ctrl_skt = INVALID_SOCKET then
  begin
    DOAddLine('Connection failed '+HOST_IP);
    DOAddLine('통신오류: 소켓핸들을 얻을 수 없습니다.');
    System.Exit;
  end;
  // 비동기 접속
  asyncconnect(ctrl_skt, Server_in, ASYNC_TIMEOUT_SEC);
  if BB_Stop.Tag = 1 then // 중지비튼을 눌렀다
  begin
    DOAddLine('Connection failed '+HOST_IP);
    DOAddLine('중지버튼을 눌렀습니다.');
    DOclosesocket(ctrl_skt);
    System.Exit;
  end
  else if BB_Stop.Tag = 2 then // 연결시도중 에러발생
  begin
    DOAddLine('Connection failed '+HOST_IP);
    DOAddLine('FTP서버에 연결을 못했습니다.');
    DOclosesocket(ctrl_skt);
    System.Exit;
  end
  else if BB_Stop.Tag <> 5 then 
  begin
    DOAddLine('Connection failed '+HOST_IP);
    DOAddLine('FTP서버에 연결을 못했습니다. (시간제한 초과)');
    DOclosesocket(ctrl_skt);
    System.Exit;
  end;
  BB_Stop.Tag := 0;
  if GetReply then // Get banner
  begin
    // Intermediate 검사 (예, welcome banner)
    // 응답의 4번째에 '-'문자를 넣어 comment 를 보내온다
    // Intermediate인 경우는 다시 메시지를 받아야 한다
    if Copy(ReplyMsg,4,1) = '-' then
      GetReply;
    if CompareStr(C220, Copy(ReplyMsg,1,3)) <> 0 then
    begin
      DOAddLine('Connection failed '+HOST_IP);
      DOAddLine('FTP서버에 연결을 못했습니다.');
      DOclosesocket(ctrl_skt);
      System.Exit;
    end;
  end;
  if BB_Stop.Tag <> 0 then
  begin
    DOAddLine('Connection failed '+HOST_IP);
    DOclosesocket(ctrl_skt);
    System.Exit;
  end;
  DOAddLine('Connected to '+HOST_IP+'  port '+IntToStr(SERVER_PORT));
  if ReplyMsg <> '' then
    DOAddLine(ReplyMsg);
  Comd := PUT_USER;
  if not Send_Command('USER ' + USER_ID) then
  begin
    DOAddLine('Connection failed '+HOST_IP);
    DOclosesocket(ctrl_skt);
    System.Exit;
  end;
  if not Send_Command('TYPE '+TRAN_MODE) then
  begin
    DOAddLine('전송실패: TYPE 명령어를 실행할 수 없습니다');
    DOclosesocket(ctrl_skt);
    System.Exit;
  end;
  i := SizeOf(Local_in);
  // GetSockname() 함수는 현재 소켓에 할당된 내쪽 주소(IP주소+포트번호)를 얻어내는 함수이다
  // 이 함수는 bind()로 내쪽 주소를 지정하지 않고 connect()를 이용하여 연결이 이루어진 후
  // TCP/IP 커널에 의해 할당된 내쪽 주소를 알아낼때 사용한다
  // 만약 연결(connect)이 이루어지지 않은 상태에서 이 함수를 호출하면 내쪽 IP 주소가 할당되지
  // 않기 때문에 INADDR_ANY에 해당하는 값의 주소가 리턴된다.
  if GetSockname(ctrl_skt, Local_in, i) = SOCKET_ERROR then // Local_in 은 여기서 한번만 setting된다
  begin
    DOAddLine('통신오류: Packet Driver 에러로 로컬주소를 얻지못했습니다.');
    DOclosesocket(ctrl_skt);
    System.Exit;
  end;
  Send_HostFile(SEND_FILENAME, RECV_FILENAME, True);
  if CompareStr(C226, Copy(ReplyMsg,1,3)) = 0 then // 226 = Transfer complete
    Result := True;
end;
// 하나의 host file을 Local로 전송(SendFile, RecvFile은 full path로 지정되있다)
function TFTPGetForm.Send_HostFile(SendFile, RecvFile: String; BinFile: Boolean): Boolean;
var
  OutF: file;
  i, iNumRead, iNumWrite: Integer;
  cnt, accum: Integer;
  MsgBuf: array[0..RECV_BYTE] of Char; {전송 버퍼}
begin
  Result := False; // 전송실패
  {$I-}
  FileMode := 1;   {write Only}
  AssignFile(OutF, RecvFile); // full path
  ReWrite(OutF, 1); {Record Size 1(byte단위)}
  {$I+}
  if IOResult <> 0 then
  begin
    DOAddLine('로컬에 파일 '''+RecvFile+''' 를 만들 수 없습니다.');
    System.CloseFile(OutF);
    System.Exit;
  end;
  if GetFTPListenSocket = INVALID_SOCKET then   {listen socket을 얻은후 "PORT"명령을 보내는 함수호출후 비교}
  begin
    System.CloseFile(OutF);
    System.Exit;
  end;
  if PASSIVE_MODE then // passive mode
  begin
    // PASV 명령에의해 서버로 부터 할당받은 IP와 port번호로 직접 접속하여
    // 자료를 가져온다(data_skt은 GetFTPListenSocket 에서 생성시켰음)
    // 비동기 접속
    asyncconnect(data_skt, Data_in, ASYNC_TIMEOUT_SEC);
    if BB_Stop.Tag = 1 then // 중지비튼을 눌렀다
    begin
      System.CloseFile(OutF);
      DOclosesocket(data_skt);
      System.Exit;
    end
    else if BB_Stop.Tag = 2 then // 연결시도중 에러발생
    begin
      System.CloseFile(OutF);
      DOAddLine('통신오류: 데이타를 수신할 수 없는 상태입니다.');
      System.Exit;
    end
    else if BB_Stop.Tag = 3 then // Timeout
    begin
      System.CloseFile(OutF);
      DOclosesocket(data_skt);
      DOAddLine('통신오류: 데이타 수신이 지연됩니다.');
      System.Exit;
    end;
    Comd := PUT_RETR; {파일size를 구한다}
    if not Send_Command('RETR '+SendFile) then // full path
    begin
      System.CloseFile(OutF);
      DoCloseSocket(data_skt);
      if (BB_Stop.Tag = 1) and (CompareStr(C226, Copy(ReplyMsg,1,3)) <> 0) then // 226 = Transfer complete
      begin
        AbortCom;
      end;
      System.Exit;
    end;
    if Copy(ReplyMsg,1,1) = '5' then
    begin
      System.CloseFile(OutF);
      DoCloseSocket(data_skt);
      MessageDlg('서버에 실행파일이 없거나 사용할 수 없습니다',
                 mtInformation, [mbOk], 0);
      Timer1.Enabled := True; // 약간 지연시킨후 종료                 
      System.Exit;
    end;
    
    if RecvFileSize < 0 then
    begin
      System.CloseFile(OutF);
      DoCloseSocket(data_skt);
      System.Exit;
    end;
  end
  else
  begin
    Comd := PUT_RETR; {파일size를 구한다}
    if not Send_Command('RETR '+SendFile) then // full path
    begin
      DoCloseSocket(listen_skt);
      System.CloseFile(OutF);
      if (BB_Stop.Tag = 1) and (CompareStr(C226, Copy(ReplyMsg,1,3)) <> 0) then // 226 = Transfer complete
      begin
        AbortCom;
      end;
      System.Exit;
    end;
    if Copy(ReplyMsg,1,1) = '5' then
    begin
      System.CloseFile(OutF);
      DoCloseSocket(data_skt);
      MessageDlg('서버에 실행파일이 없거나 사용할 수 없습니다',
                 mtInformation, [mbOk], 0);
      Timer1.Enabled := True; // 약간 지연시킨후 종료                 
      System.Exit;
    end;
    if RecvFileSize < 0 then
    begin
      DoCloseSocket(listen_skt);
      System.CloseFile(OutF);
      System.Exit;
    end;
    asyncselect(listen_skt, True); // 두번째가 True인것은 지정한 소켓이 recv용 소켓임을 표시
    if BB_Stop.Tag <> 0 then
    begin
      DoCloseSocket(listen_skt);
      System.CloseFile(OutF);
      if (BB_Stop.Tag = 1) and (CompareStr(C226, Copy(ReplyMsg,1,3)) <> 0) then // 226 = Transfer complete
      begin
        AbortCom;
      end;
      System.Exit;
    end;
    accum := SizeOf(Data_in);
    Data_skt := accept(listen_skt, @Data_in, @accum); {listen socket에서 대기}
    if Data_skt = INVALID_SOCKET then
    begin
      DoCloseSocket(listen_skt);
      DoCloseSocket(Data_skt);
      System.CloseFile(OutF);
      System.Exit;
    end;
    DoCloseSocket(listen_skt); {data송수신시 Listen socket은 필요없으므로 닫는다}
  end;
  L_Rsize.Caption := '0/'+IntToStr(RecvFileSize div 1024)+' KB';
  iNumRead  := 0;
  iNumWrite := 0;
  accum     := 0;
  cnt       := TRANS_STEPBY - 1;
  trans_bps := 0;
  while True do
  begin
    trans_time := GetTickCount; // 시작 TimeOut
    asyncselect(Data_skt, True); // 두번째가 True인것은 지정한 소켓이 recv용 소켓임을 표시
    if BB_Stop.Tag <> 0 then
    begin
      Break;
    end;
    iNumRead := recv(Data_skt, MsgBuf, SizeOf(MsgBuf), 0);
    if iNumRead = SOCKET_ERROR then
    begin
      System.CloseFile(OutF);
      DOAddLine('통신오류: 데이터를 받을 수 없습니다.');
      System.Exit;
    end;
    if iNumRead <= 0 then
      Break;
    BlockWrite(OutF, MsgBuf, iNumRead, iNumWrite);
    Inc(accum, iNumWrite);
    trans_time := (GetTickCount - trans_time) / 1000; // 종료 TimeOut
    if RecvFileSize > 0 then
    begin
      ProgressBar1.Position := (accum * 100) div RecvFileSize;
      L_Rsize.Caption := IntToStr(accum div 1024)+'/'+IntToStr(RecvFileSize div 1024)+' KB';
      if trans_time > 0 then
      begin
        Inc(cnt);
        trans_bps := trans_bps + (iNumRead / trans_time);
        if (cnt mod TRANS_STEPBY) = 0 then
        begin
          trans_bps := trans_bps / TRANS_STEPBY; // 평균을 구한다
          if trans_bps > 1024 then
            L_Speed.Caption := Format('at %.1f Kbps',[trans_bps / 1024])
          else if trans_bps > 0 then
            L_Speed.Caption := Format('at %.0f bps',[trans_bps]);
        end;
      end;
    end;
    Application.ProcessMessages;
    if BB_Stop.Tag <> 0 then {Cancel이 click되면}
      Break;
  end; {while}
  System.CloseFile(OutF);
  if BB_Stop.Tag = 1 then // 중지이면 Abort 메시지를 보내서 data connection을 취소
  begin
    DoCloseSocket(Data_skt); {data control 소켓을 닫는다}
    if CompareStr(C226, Copy(ReplyMsg,1,3)) <> 0 then // 226 = Transfer complete
    begin
      AbortCom;
    end;
    System.Exit;
  end
  else if BB_Stop.Tag = 2 then // 에러
  begin
    DOAddLine('통신오류: 데이타를 수신할 수 없는 상태입니다.');
    system.Exit;
  end;
  ProgressBar1.Position := 100;
  DoCloseSocket(Data_skt); {data control 소켓을 닫는다}
  
  if CompareStr(C226, Copy(ReplyMsg,1,3)) <> 0 then // 226 = Transfer complete
    if GetReply then
    begin
      if Copy(ReplyMsg,4,1) = '-' then
        GetReply;
      if ReplyMsg <> '' then
        DOAddLine(ReplyMsg);
    end;
  Result := True;
end;
{Data Connection(listen socket을 얻는다)}
function TFTPGetForm.GetFTPListenSocket: TSocket;
var
  i: Integer;
  a, p: PChar; {a:address, p:port}
  passiveIP: String;
  PasvAddress: DWord; // 이진의 IP주소(4 bytes)
  PasvPort: Word;
begin
  // GetFTPListenSocket() 의 리턴값은 PASV 모드인 경우는 data_skt 을
  // 그렇지 않으면 listen_skt 을 리턴한다
  DOclosesocket(Listen_skt);  {이전 소켓이 열려있을 수 있으므로 닫는다}
  DOclosesocket(Data_skt);
  Result := INVALID_SOCKET;
  // Use PASV Mode
  // PASV mode is supported as a firewall option.
  // This feature simply reverses the connection between host and server,
  // thus allowing many users that reside behind firewalls to use this program.
  // PASV mode ftp is what most of the browsers like Netscape,
  // and Microsoft use to initiate ftp transfers.
  if PASSIVE_MODE then // PASV 모드
  begin
    Comd := GET_MESSAGE;
    if not Send_Command('PASV') then {Use PASV Mode}
      System.Exit;
    if CompareStr(C227, Copy(ReplyMsg,1,3)) <> 0 then {C227 = "Entering Passive Mode (130,33,2,28,4,62)"}
    begin
      if ReplyMsg <> '' then
        DOAddLine(ReplyMsg);
      Result := INVALID_SOCKET;
    end
    else
    begin
      passiveIP := copy(ReplyMsg, pos('(', ReplyMsg) + 1, length(ReplyMsg));
      passiveIP := copy(passiveIP, 1, pos(')', passiveIP) - 1); // passiveIP = "130,33,2,28,4,62"
      // 인터넷의 IP주소를 의미하는 문자열은 네 개의 숫자와 그들을 구분하는 도트(".')
      // 로 구성된다. 그래서 inet_addr은 그 문자열에 해당하는 네트워크 바이트 순서로
      // 된 이진의 IP주소를 리턴한다(4 bytes).
      PasvAddress := inet_addr(PChar(Get_Value(passiveIP,',',1)+'.'+
                                     Get_Value(passiveIP,',',2)+'.'+
                                     Get_Value(passiveIP,',',3)+'.'+
                                     Get_Value(passiveIP,',',4)));
      PasvPort := StrToIntDef(Get_Value(passiveIP,',',5),0) shl 8 +
                  StrToIntDef(Get_Value(passiveIP,',',6),0); // 네트워크 바이트 순서의 port 번호
      Data_skt := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
      if Data_skt = INVALID_SOCKET then
      begin
        DOAddLine('통신오류: 데이터 소켓핸들을 얻을 수 없습니다.');
        Result := INVALID_SOCKET;
        System.Exit;
      end;
      Result := Data_skt;
      // passive mode 에서는 data socket의 IP와 port 번호를 서버가 임의로
      // 할당하므로 이를 이용하여 listen, accept하지 않고 바로 data socket으로
      // connect하여 자료를 가져온다
      with Data_in do
      begin
        FillChar(Data_in, SizeOf(Data_in), #0);
        sin_family          := PF_INET;
        sin_addr.s_addr     := PasvAddress; // 서버가 할당한 IP
        sin_port            := htons(PasvPort); // 서버가 할당한 port number (data port)
      end;
    end;
  end
  else // PORT 모드
  begin
    Listen_skt := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if Listen_skt = INVALID_SOCKET then
    begin
      DOAddLine('통신오류: 데이터 소켓핸들을 얻을 수 없습니다.');
      Result := INVALID_SOCKET;
      System.Exit;
    end;
    // 만일 IP주소가 INADDR_ANY 이면 실제 이 소켓이 사용될 때는 내 호스트가 연결된
    // 여러 개의 네트워크 가운데 상대방 호스트에 따라 적합한 네트워크를 선택하고
    // 그에 해당하는 주소로 바뀐다
    with Listen_in do
    begin
      FillChar(Listen_in, SizeOf(Listen_in), #0);
      sin_family          := PF_INET;
      sin_addr.s_addr     := htonl(INADDR_ANY);
      sin_port            := htons(0);
    end;
    // bind()함수는 스트림 소켓과 데이터그램 소켓 등 양쪽 형태의 아직 연결이 되지 않은
    // 소켓에 대해 connect()나 listen() 함수를 호출하기 이전에 내쪽의 주소(IP, port)
    // 를 구체적으로 지정하기 위해 사용
    if bind(Listen_skt, Listen_in, SizeOf(Listen_in)) = SOCKET_ERROR then
    begin
      DOAddLine('통신오류: 데이터 바인딩을 못했습니다.');
      Result := INVALID_SOCKET;
      System.Exit;
    end;
    i := SizeOf(Listen_in);
    if getsockname(Listen_skt, Listen_in, i) < 0 then  {내쪽의 주소(IP + port)를 알아낸다}
    begin
      DOAddLine('통신오류: 데이터 포트번호를 얻지 못했습니다.(data control)');
      Result := INVALID_SOCKET;
      System.Exit;
    end;
    // listen() 함수는 스트림 소켓의 TCP 상태를 LISTEN 상태, 즉 연결을 기다리는 상태로 만든다
    // 따라서 listen()은 연결을 지원하는 스트림 소켓에만 적용되는 함수이다
    if Listen(Listen_skt, 1) = SOCKET_ERROR then
    begin
      DOAddLine('통신오류: 데이터를 받을 수 없습니다.');
      Result := INVALID_SOCKET;
      System.Exit;
    end;
    {port번호를 생성하여 "PORT"명령을 송신하여 클라이언트의 receive 포트를 서버에 알린다}
    a := PChar(@(Local_in.sin_addr));  {local IP address, login 시 구해놨음}
    p := PChar(@(Listen_in.sin_port)); {listen socket(htons(0)에 의해 생성된 port}
    Comd := PUT_PORT;
    if not Send_Command(
         Format('PORT %d,%d,%d,%d,%d,%d',[Byte(a[0]) and $00ff
                                         ,Byte(a[1]) and $00ff
                                         ,Byte(a[2]) and $00ff
                                         ,Byte(a[3]) and $00ff
                                         ,Byte(p[0]) and $00ff
                                         ,Byte(p[1]) and $00ff])) then
    begin
      DOclosesocket(Listen_skt);
      DOclosesocket(Data_skt);
      if BB_Stop.Tag = 1 then
      begin
        AbortCom;
      end;
      System.Exit;
    end;
                                           
    if CompareStr(C200, Copy(ReplyMsg,1,3)) <> 0 then {C200 = "200 PORT command successful."}
      Result := INVALID_SOCKET
    else
      Result := Listen_skt;
  end;
end;
function TFTPGetForm.AbortCom: Boolean;
begin
  Result := False;
  BB_Stop.Tag := 0;
  Comd := GET_MESSAGE;
  if not Send_Command('ABOR') then
  begin
    DOAddLine('transfer failed');
    DOAddLine('전송이 취소되었습니다');
    System.Exit;
  end;
  if GetReply then
  begin
    if Copy(ReplyMsg,4,1) = '-' then
      GetReply;
    if ReplyMsg <> '' then
      DOAddLine(ReplyMsg);
  end;
  Result := True;
end;
{Command전송후 reply message를 처리
 multiline 메시지수신(첫번째 message만 ReplyMsg변수에 받고 나머지는 삭제}
procedure TFTPGetForm.Process_ReplyMessage;
var
  i, j: integer;
  SubStr: String;
begin
  if (ctrl_skt = SOCKET_ERROR) then
  begin
    BB_Stop.Tag := 2;
    System.Exit;
  end;
  case Comd of {Comd 전역변수에는 현재 FTP명령어의 종류를 저장하고 있음}
    PUT_USER:
      begin
        if ReplyMsg = '' then // 응답이 없었다면(가끔 proxy서버에서 발생) 다시 받는다
        begin
          if GetReply then // Get banner
          begin
            if Copy(ReplyMsg,4,1) = '-' then
              GetReply;
          end;
        end;
        if Copy(ReplyMsg,1,1) = '2' then {"230 User 사용자ID logged in."}
        begin
          DOAddLine(ReplyMsg);
        end
        else if Copy(ReplyMsg,1,1) = '3' then {"331 Password required for 사용자ID"}
        begin
          DOAddLine(ReplyMsg);
          Comd := PUT_PASS;
          if not Send_Command('PASS ' + PASSWORD) then {password전송}
          begin
            BB_Stop.Tag := 2;
            System.Exit;
          end;
        end
        else // 530 User ... Unknown
        begin
          if ReplyMsg <> '' then
            DOAddLine(ReplyMsg);
          DOAddLine('사용자ID가 틀립니다.');
          BB_Stop.Tag := 2;
        end;
      end;
    PUT_PASS:
      begin
        if Copy(ReplyMsg,1,1) = '2' then {"230 User 사용자ID logged in."}
        begin
          DOAddLine(ReplyMsg);
        end
        else if Copy(ReplyMsg,1,1) = '3' then {계정필요}
        begin
          DOAddLine(ReplyMsg);
          Comd := PUT_ACCT;
          if not Send_Command('ACCT '+USER_ID) then
          begin
            BB_Stop.Tag := 2;
            System.Exit;
          end;
        end
        else // 530 Login incorrect
        begin
          if ReplyMsg <> '' then
            DOAddLine(ReplyMsg);
          DOAddLine('사용자ID의 비밀번호가 틀립니다.');
          BB_Stop.Tag := 2;
        end;
      end;
    PUT_ACCT:
      begin
        if Copy(ReplyMsg,1,1) = '2' then {"230 User 사용자ID logged in."}
        begin
          DOAddLine(ReplyMsg);
        end
        else // 530 Login incorrect
        begin
          if ReplyMsg <> '' then
            DOAddLine(ReplyMsg);
          DOAddLine('사용자ID의 계정(Account)이 틀립니다.');
          BB_Stop.Tag := 2;
        end;
      end;
    PUT_PORT:
      begin
        if CompareStr(C200, Copy(ReplyMsg,1,3)) <> 0 then {C200 = "일반명령어의 실행 성공"}
          DOclosesocket(Listen_skt);
        if ReplyMsg <> '' then
          DOAddLine(ReplyMsg);
      end;
    PUT_RETR:
      begin
        RecvFileSize := -1; // -1은 에러, 0은 파일 크기가 0인것을 의미
        if ReplyMsg <> '' then
          DOAddLine(ReplyMsg);
        if CompareStr(C150, Copy(ReplyMsg,1,3)) = 0 then {C150 = "Opening data connection for xxxxxxxx.xxxx"}
        begin
          for i := Length(ReplyMsg) downto 1 do
            if ReplyMsg[i] = '(' then
            begin
              ReplyMsg := Copy(ReplyMsg, i, MAX_PATH); // (99999) 만 뽑아낸다
              Break;
            end;
          i := Pos('(', ReplyMsg); {메시지에서 Retrieve할 파일의 size를 추출}
          if i > 0 then
          begin
            SubStr := '';
            for j := i+1 to System.Length(ReplyMsg) do
              if ReplyMsg[j] in ['0','1','2','3','4','5','6','7','8','9'] then
                AppendStr(SubStr,ReplyMsg[j]);
            RecvFileSize := StrToIntDef(SubStr, 0);
          end
          else
          begin
            // "150 Opening data connection for xxxx" 에 파일 사이즈를 안주는 서버가 있음
            // 이때는 RecvFileSize 의 최대 크기를 주어 파일은 받게한다
            RecvFileSize := High(RecvFileSize);
          end;
        end
        else if CompareStr(C226, Copy(ReplyMsg,1,3)) = 0 then // 226 = Transfer complete
        begin
          // RETR 하자마자 "226 = Transfer complete" 이 오는것은 파일의 크기가 너무 작을때 발생한다
          RecvFileSize := RECV_BYTE; // -1은 에러, 0은 파일 크기가 0인것을 의미
        end;
      end;
    GET_MESSAGE:
      begin
        if ReplyMsg <> '' then
          DOAddLine(ReplyMsg);
      end;
    PUT_QUIT: {program end}
      begin
        if ReplyMsg <> '' then
          DOAddLine(ReplyMsg);
      end;
  end; {case}
end;
{FTP서버에 명령어 전송 프로시져}
function TFTPGetForm.Send_Command(cStr: String): Boolean;
begin
  Result := False;
  if ctrl_skt = INVALID_SOCKET then
  begin
    System.Exit;
  end;
  asyncselect(ctrl_skt, False); // 두번째가 False인것은 지정한 소켓이 send용 소켓임을 표시
  if BB_Stop.Tag <> 0 then
  begin
    System.Exit;
  end;
  if Copy(cStr,1,4) = 'PASS' then
    DOAddLine('PASS (hidden)') // password를 보여주지 않고 감춘다
  else
    DOAddLine(cStr);
  FillChar(SendBuff, SizeOf(SendBuff), #0);
  AppendStr(cStr, #13#10);  {CR/LF문자 추가}
  StrPcopy(SendBuff, cStr);
  if Send(ctrl_skt, SendBuff, StrLen(SendBuff), 0) = SOCKET_ERROR then
  begin
    System.Exit;
  end;
  if GetReply then
  begin
    // Intermediate 검사 (예, welcome banner)
    // 응답의 4번째에 '-'문자를 넣어 comment 를 보내온다
    // Intermediate인 경우는 다시 메시지를 받아야 한다
    if Copy(ReplyMsg,4,1) = '-' then
      GetReply;
    Process_ReplyMessage;
  end;
  if BB_Stop.Tag <> 0 then
  begin
    System.Exit;
  end;
  Result := True;
end;
{reply message를 메시지 listbox에 출력}
procedure TFTPGetForm.DOAddLine(str: String);
begin
  CB_Message.ItemIndex := CB_Message.Items.Add(str);
  Application.ProcessMessages;
end;
{FTP서버로 부터의 메시지를 받는 함수}
function TFTPGetForm.GetReply: Boolean;
var
  i, iNumByte: Integer;
begin
  // 복수 메시지일 경우 마지막 메시지를 응답으로 처리한다
  ReplyMsg := '';
  Result := False;
  if ctrl_skt = INVALID_SOCKET then
  begin
    BB_Stop.Tag := 2;
    System.Exit;
  end;
  if BB_Stop.Tag <> 0 then
  begin
    System.Exit;
  end;
  asyncselect(ctrl_skt, True); // 두번째가 True인것은 지정한 소켓이 recv용 소켓임을 표시
  if BB_Stop.Tag <> 0 then
  begin
    System.Exit;
  end;
  FillChar(RecvBuff, SizeOf(RecvBuff), #0);
  iNumByte := recv(ctrl_skt, RecvBuff, SizeOf(RecvBuff), 0);
  if iNumByte = SOCKET_ERROR then
  begin
    BB_Stop.Tag := 2;
    System.Exit;
  end;
  for i := 0 to iNumByte - 1 do
    if (RecvBuff[i] = #0) or (RecvBuff[i] = #10) then {각 message의 구분문자}
    begin
      if i = (iNumByte - 1) then // 하나의 메시지만 있는경우
      begin
        Break;
      end;
      // * 마지막 메시지가 아닌것은 그냥 화면에 보여준다 *
      // Intermediate 검사 (예, welcome banner)
      // 응답의 4번째에 '-'문자를 넣어 comment 를 보내온다
      // Intermediate인 경우는 다시 메시지를 받아야 한다
      if Trim(ReplyMsg) <> '' then
        DOAddLine(Trim(ReplyMsg));
      ReplyMsg := '';
    end
    else
      ReplyMsg := ReplyMsg + RecvBuff[i];
  ReplyMsg := Trim(ReplyMsg); // 문자열에 #13(CR)이 포함될 수 있으므로 제거하는 의미에서 Trim 시킴
  Result := True;
end;
{열려있는 모든 소켓을 닫는다}
procedure TFTPGetForm.AllCloseSocket;
begin
  if ctrl_skt <> INVALID_SOCKET then
    DOclosesocket(ctrl_skt);
  if listen_skt <> INVALID_SOCKET then
    DOclosesocket(listen_skt);
  if Data_skt <> INVALID_SOCKET then
    DOclosesocket(Data_skt);
end;
procedure TFTPGetForm.asyncselect(synsocket: Tsocket; readsock: Boolean);
// 이 함수는 원래 WSAAsyncSelect() 함수를 사용하여 비동기 원속 메시지를
// 처리하여야 하지만 이 프로그램에서는 BSD 계열의 소켓 함수인 select()
// 함수를 사용하여 비동기 처리를 하였습니다  
begin
  if readsock = True then // recv
    FD_ZERO(readfds)
  else
    FD_ZERO(writefds);
  // select() 함수는 BSD 계열의 소켓 함수(소켓함수는 크게 3가지로 분류하는데
  // BSD 계열의 함수, 데이터베이스 함수, 원도우즈 지원함수로 분류) 로
  // 지정된 하나 또는 여러 개의 소켓에 대해 수신된 데이터가 있는지,
  // 송신이 가능한지, OOB(대역외 데이터) 가 수신되었는지를 체크하기 의한
  // 폴링(polling)함수이다
  // 함수의 리턴값은 select()가 성공적으로 이루어지면 리턴된 readfds,
  // writefds, exceptfds 중에 어느 하나라도 지정된 동작이 가능한 소켓의
  // 총 수가 리턴된다. 지정된 시간동안 어떤 소켓에 대해서도 지정한 동작의
  // 가능성이 없었다면 select()는 0으로 곧바로 리턴한다. 만일 select()에 체크
  // 하라고 지정한 스트림(stream) 소켓 중 하나라도 연결이 끊어진 상태라면
  // select()는 SOCKET_ERROR 를 리턴하며 에러 코드가 설정된다
  TimeVal.tv_sec  := 0; // 대기시간 없음
  TimeVal.tv_usec := 0;
  readycomm := 0;
  while True do
  begin
    Application.ProcessMessages; // 대기상태인동안 원도우즈의 메세지처리
    if readsock = True then // recv
    begin
      FD_SET(synsocket, readfds);
      readycomm := select(synsocket+1, @readfds, nil, nil, @TimeVal) // 0..synsocket까지의 socket 검사
    end
    else
    begin
      FD_SET(synsocket, writefds);
      readycomm := select(synsocket+1, nil, @writefds, nil, @TimeVal);
    end;
    if BB_stop.Tag = 1 then {중지버튼 클릭}
      System.Exit;
    if (readycomm > 0) then // 지정된 동작을 할 수 있는 소켓의 갯수
    begin
      if (readsock = True) and (FD_ISSET(synsocket, readfds) = True) then
      begin
        BB_Stop.Tag := 0;
        System.Exit;
      end
      else if (readsock = False) and (FD_ISSET(synsocket, writefds) = True) then
      begin
        BB_Stop.Tag := 0;
        System.Exit;
      end
    end;
  end;
end;
procedure TFTPGetForm.asyncconnect(synsocket: Tsocket; synsocket_in: TSockAddrIn; trytimes: Integer);
var
  argp: Longint;
begin
  // WSAAsyncSelect()은 네트워크 이벤트(FD_ACCEPT, FD_READ, FD_WRITE, FD_CLOSE...)중 하나라도 소켓에 발생했을때
  // 지정된 원도우에 메시지를 보낸다. 이 함수를 호출하면 소켓은 자동적으로 Non-Blocking 모드로 바뀐다.
  // 이 메시지의 wParam에는 소켓이, lParam의 하위 16비트에는 발생한 이벤트, 상위 16비트에는 에러코드가
  // 저장된다.
  // 여러개의 네트워크 이벤트가 동시에 발생했다면, 원도우는 각 이벤트에 대하여 각각의 메시지를 받게 된다
  WSAAsyncSelect(synsocket, Self.Handle, WM_CONNECT_MSG, FD_CONNECT);
  Start_Time := GetTickCount; // 시작 TimeOut
  if Connect(synsocket, synsocket_in, sizeof(synsocket_in)) = SOCKET_ERROR then
    if WSAGetLastError <> WSAEWOULDBLOCK then
    begin
      BB_Stop.Tag := 2;
      System.Exit;
    end;
  repeat
    Application.ProcessMessages; {allowing access to other controls, etc.}
    if BB_Stop.Tag <> 0 then // 중지비튼을 눌렀거나 연결되거나 에러발생(BB_Stop.Tag의 값은 AppMessage에서 바꿈)
      Break;
  until ((GetTickCount-Start_Time) >= Longint(trytimes * 1000)); // TimeOut 검사
  if (BB_Stop.Tag <> 1) and (BB_Stop.Tag <> 2) and (BB_Stop.Tag <> 5) then // 에러나 연결이 아니면 시간초과
  begin
    BB_Stop.Tag := 3;
    System.Exit;
  end;
  
  // WSAAsyncSelect()함수를 호출하면 소켓은 자동적으로 Non-Blocking 모드로 바뀌는데
  // 이를 Blocking모드로 다시 변경한다
  // 소켓을 Blocking 모드로 다시 전환하기 위해서는 먼저 WSAAsyncSelect()의 lEvent 인자를 0으로
  // 하여 호출하고 ioctlsocket() 함수를 호출해야 한다
  WSAAsyncSelect(synsocket, Self.Handle, 0, 0);
  argp := 0; // Non-Blocking 모드 해제
  ioctlsocket(synsocket, FIONBIO, argp);
end;
procedure TFTPGetForm.ConnectMessage(var Msg: TMessage);
begin
  if (WSAGetSelectEvent(Msg.lParam) = FD_CONNECT) and // 이전에 요청한 연결이 이루어짐
     (WSAGetSelectError(Msg.lParam) = 0) // 상위 16비트에는 에러코드가 있음
  then
    BB_Stop.Tag := 5  // 0:초기/정상, 1:중지, 2:에러, 5:연결
  else
    BB_Stop.Tag := 2;
end;
{parameter로 지정한 소켓을 강제로 즉시 닫는다(블록킹 해제됨)}
procedure TFTPGetForm.DOclosesocket(var socket_id: TSocket);
begin
  // 블록킹(blocking)된 소켓함수가 있다면 이를 취소시킨다
  // 어느 경우에나 WSACancelBlockingCall() 이 호출되면 Block이 진행 중이던
  // 원래의 함수는 에러로 리턴하고, 이 때 에러 코드는 WSAEINTR이 된다
  // 이식성이 높은 응용 프로그램을 개발하기 위하여 WSACancelBlockingCall() 후에
  // closesocket() 이외의 다른 소켓 함수 호출은 하지 않는 것이 좋다.
  if socket_id <> INVALID_SOCKET then
    if WSAISBlocking then // 어떤 소켓 함수가 Block 상태에 있는 가를 검사
    begin
      WSACancelBlockingCall;
      DOAddLine('Cancelled blocking call');
    end;
  CloseSocket(socket_id);
  socket_id := INVALID_SOCKET;
end;
{cSpr 문자로 분리된 문자열에서 nPos번째 문자열을 return}
function TFTPGetForm.Get_Value(Str, cSpr:String; nPos: Integer): String;
var
  i, j, cnt: Integer;
begin
  if Pos(cSpr, Str) = 0 then
  begin
    Result := Str;
    System.Exit;
  end;
  i := 1;
  j := 1;
  cnt := 1; {cSpr 문자 갯수}
  while i <= Length(Str) do
  begin
    if Str[i] = cSpr then
    begin
      if cnt = nPos then
      begin
        Result := Copy(Str, j, i - j);
        System.Exit;
      end;
      Inc(cnt);
      j := i + 1;
    end;
    Inc(i);
  end;
  if nPos = cnt then {맨 마지막 문자열을 원했을때}
    Result := Copy(Str, j, i - j + 1)
  else
    Result := ''; {해당값 없음}
end;
procedure TFTPGetForm.FormActivate(Sender: TObject);
var
  ImsiFile: String;
begin
  ImsiFile := ExtractFilePath(RECV_FILENAME)+
              Copy(ExtractFileName(RECV_FILENAME),1,Pos('.',ExtractFileName(RECV_FILENAME))-1)+'.bak';
  if FileExists(RECV_FILENAME) or FileExists(ImsiFile) then // 해당파일이나 backup파일이 있다면 Update!
    Image_update.Visible := True
  else
    Image_new.Visible := True;
  Application.ProcessMessages;
  BB_Stop.Tag := 0;
  BB_Stop.Caption := '중지(&C)';
  ProgressBar1.Position := 0;
  L_Rsize.Caption := '';
  CB_Message.Items.Clear;
  Application.ProcessMessages;
  FTPTransfered := FTP_connect;
  Application.ProcessMessages;
  AllCloseSocket;
  BB_Stop.caption := '닫기(&C)';
  if FTPTransfered then // 전송완료
  begin
    Timer1.Enabled := True; // 약간 지연시킨후 종료
  end;
end;
procedure TFTPGetForm.BB_StopClick(Sender: TObject);
begin
  BB_Stop.Tag := 1;
  Application.ProcessMessages;
  Close;
end;
procedure TFTPGetForm.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := False;
  Close;
end;
procedure TFTPGetForm.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  Image_update.Visible := False;
  Image_new.Visible    := False;
  CanClose := True;
end;
end.
			 
	
	
    
    
	
	
    
    
    
이거 ftp관련댄게 데모에 이뜨라구여. 그래서 일케 쓰는데 분석은 못하구여--;;
여기 업로드 기능 이뜨라구여. 그거 보시구 하믄 대겐네여 ^^;
아공 위치는 C:Program FilesBolandDelphi5DemosFastNetFtp 네요.
구럼 도움이 되시길 간절히 바라면서 ㅜ.ㅜ 초보는 물러갑니당...
///////////////////////////////////////////////////////////////////////////
// //
// Copyright ?1997-1998, NetMasters, L.L.C //
// - All rights reserved worldwide. - //
// Portions may be Copyright ?Inprise. //
// //
// FTP Demo Unit 1 : (UNIT1.PAS) //
// //
// DESCRIPTION: //
// //
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY //
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE //
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR //
// PURPOSE. //
// //
///////////////////////////////////////////////////////////////////////////
//
// Revision History
//
// //
///////////////////////////////////////////////////////////////////////////
unit FTPDem;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Forms, Dialogs,
ComCtrls, StdCtrls, Psock, NMFtp, Controls;
type
TForm1 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
TabSheet3: TTabSheet;
TabSheet4: TTabSheet;
HostTxt: TEdit;
PortTxt: TEdit;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
StatusBar1: TStatusBar;
Memo1: TMemo;
Button3: TButton;
Button4: TButton;
NMFTP1: TNMFTP;
UserTxt: TEdit;
Label3: TLabel;
PassTxt: TEdit;
Label4: TLabel;
DirTxt: TEdit;
Label5: TLabel;
Label6: TLabel;
Button5: TButton;
RemoteTxt: TEdit;
Label7: TLabel;
LocalTxt: TEdit;
Label8: TLabel;
Button6: TButton;
Button7: TButton;
TabSheet6: TTabSheet;
Edit3: TEdit;
Label11: TLabel;
Label12: TLabel;
Edit4: TEdit;
Button10: TButton;
Button11: TButton;
Button8: TButton;
Button9: TButton;
Button12: TButton;
Button13: TButton;
PosTxt: TEdit;
Label9: TLabel;
TabSheet5: TTabSheet;
Edit1: TEdit;
Label10: TLabel;
Edit2: TEdit;
Label13: TLabel;
Button14: TButton;
Button15: TButton;
TabSheet7: TTabSheet;
Edit5: TEdit;
Label14: TLabel;
Button16: TButton;
TabSheet8: TTabSheet;
Button17: TButton;
Label15: TLabel;
CheckBox1: TCheckBox;
Edit6: TEdit;
Edit7: TEdit;
Label16: TLabel;
Label17: TLabel;
TabSheet9: TTabSheet;
Edit8: TEdit;
Edit9: TEdit;
Label18: TLabel;
Label19: TLabel;
Button18: TButton;
procedure NMFTP1Success(Trans_Type: TCmdType);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure NMFTP1ListItem(Listing: String);
procedure TabSheet3MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Button5Click(Sender: TObject);
procedure Button8Click(Sender: TObject);
procedure NMFTP1PacketRecvd(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure Button10Click(Sender: TObject);
procedure Button11Click(Sender: TObject);
procedure Button12Click(Sender: TObject);
procedure Button13Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Button14Click(Sender: TObject);
procedure Button15Click(Sender: TObject);
procedure Button16Click(Sender: TObject);
procedure Button17Click(Sender: TObject);
procedure NMFTP1Connect(Sender: TObject);
procedure NMFTP1Failure(var handled: Boolean; Trans_Type: TCmdType);
procedure NMFTP1TransactionStop(Sender: TObject);
procedure NMFTP1HostResolved(Sender: TComponent);
procedure NMFTP1InvalidHost(var handled: Boolean);
procedure NMFTP1PacketSent(Sender: TObject);
procedure NMFTP1TransactionStart(Sender: TObject);
procedure NMFTP1Disconnect(Sender: TObject);
procedure NMFTP1Error(Sender: TComponent; Errno: Word; Errmsg: String);
procedure NMFTP1Status(Sender: TComponent; Status: String);
procedure Button18Click(Sender: TObject);
procedure NMFTP1UnSupportedFunction(Trans_Type: TCmdType);
procedure NMFTP1ConnectionFailed(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
var
Q: Integer;
procedure TForm1.NMFTP1Success(Trans_Type: TCmdType);
begin
Case Trans_Type of
cmdChangeDir: StatusBar1.SimpleText := 'ChangeDir success';
cmdMakeDir: StatusBar1.SimpleText := 'MakeDir success';
cmdDelete: StatusBar1.SimpleText := 'Delete success';
cmdRemoveDir: StatusBar1.SimpleText := 'RemoveDir success';
cmdList: StatusBar1.SimpleText := 'List success';
cmdRename: StatusBar1.SimpleText := 'Rename success';
cmdUpRestore: StatusBar1.SimpleText := 'UploadRestore success';
cmdDownRestore: StatusBar1.SimpleText := 'DownloadRestore success';
cmdDownload: StatusBar1.SimpleText := 'Download success';
cmdUpload: StatusBar1.SimpleText := 'Upload success';
cmdAppend: StatusBar1.SimpleText := 'UploadAppend success';
cmdReInit: StatusBar1.SimpleText := 'ReInit success';
cmdAllocate: StatusBar1.SimpleText := 'Allocate success';
cmdNList: StatusBar1.SimpleText := 'NList success';
cmdDoCommand: StatusBar1.SimpleText := 'DoCommand success';
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
If CheckBox1.Checked then
Begin
NMFTP1.Proxy := Edit6.Text;
NMFTP1.ProxyPort := StrToInt(Edit7.Text);
End;
NMFTP1.Host := HostTxt.Text;
NMFTP1.Port := StrToInt(PortTxt.Text);
NMFTP1.Timeout := 5000;
NMFTP1.UserID := UserTxt.Text;
NMFTP1.Password := PassTxt.Text;
try
NMFTP1.Connect;
except
On E:Exception do
writeln(E.message);
end
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
NMFTP1.Disconnect;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Q := 1;
try NMFTP1.Nlist; except end;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
Q := 1;
try NMFTP1.List; except end;
end;
procedure TForm1.NMFTP1ListItem(Listing: String);
begin
Memo1.Lines.Add(IntToStr(Q)+': '+Listing);
Inc(Q);
end;
procedure TForm1.TabSheet3MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
Label5.Caption := 'Current Dir: ';
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
NMFTP1.ChangeDir(DirTxt.Text);
end;
procedure TForm1.Button8Click(Sender: TObject);
begin
NMFTP1.DownloadRestore(RemoteTxt.Text, LocalTxt.Text);
end;
procedure TForm1.NMFTP1PacketRecvd(Sender: TObject);
begin
StatusBar1.SimpleText := IntToStr(NMFTP1.BytesRecvd)+' of '+IntToStr(NMFTP1.BytesTotal);
end;
procedure TForm1.Button7Click(Sender: TObject);
begin
NMFTP1.Abort;
end;
procedure TForm1.Button10Click(Sender: TObject);
begin
try NMFTP1.Upload(Edit3.Text, Edit4.Text); except end;
end;
procedure TForm1.Button11Click(Sender: TObject);
begin
try NMFTP1.UploadAppend(Edit3.Text, Edit4.Text); except end;
end;
procedure TForm1.Button12Click(Sender: TObject);
begin
try NMFTP1.UploadUnique(Edit3.Text); except end;
end;
procedure TForm1.Button13Click(Sender: TObject);
begin
try NMFTP1.UploadRestore(Edit3.Text,Edit4.Text,StrToInt(PosTxt.Text)); except end;
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
try NMFTP1.Download(RemoteTxt.Text, LocalTxt.Text); except end;
end;
procedure TForm1.Button14Click(Sender: TObject);
begin
NMFTP1.MakeDirectory(Edit1.Text);
end;
procedure TForm1.Button15Click(Sender: TObject);
begin
NMFTP1.RemoveDir(Edit2.Text);
end;
procedure TForm1.Button16Click(Sender: TObject);
begin
NMFTP1.Delete(Edit5.Text);
end;
procedure TForm1.Button17Click(Sender: TObject);
begin
NMFTP1.Reinitialize;
PageControl1.ActivePage := TabSheet2;
end;
procedure TForm1.NMFTP1Connect(Sender: TObject);
begin
StatusBar1.SimpleText := 'Connected';
end;
procedure TForm1.NMFTP1Failure(var handled: Boolean; Trans_Type: TCmdType);
begin
Case Trans_Type of
cmdChangeDir: StatusBar1.SimpleText := 'ChangeDir failure';
cmdMakeDir: StatusBar1.SimpleText := 'MakeDir failure';
cmdDelete: StatusBar1.SimpleText := 'Delete failure';
cmdRemoveDir: StatusBar1.SimpleText := 'RemoveDir failure';
cmdList: StatusBar1.SimpleText := 'List failure';
cmdRename: StatusBar1.SimpleText := 'Rename failure';
cmdUpRestore: StatusBar1.SimpleText := 'UploadRestore failure';
cmdDownRestore: StatusBar1.SimpleText := 'DownloadRestore failure';
cmdDownload: StatusBar1.SimpleText := 'Download failure';
cmdUpload: StatusBar1.SimpleText := 'Upload failure';
cmdAppend: StatusBar1.SimpleText := 'UploadAppend failure';
cmdReInit: StatusBar1.SimpleText := 'ReInit failure';
cmdAllocate: StatusBar1.SimpleText := 'Allocate failure';
cmdNList: StatusBar1.SimpleText := 'NList failure';
cmdDoCommand: StatusBar1.SimpleText := 'DoCommand failure';
end;
end;
procedure TForm1.NMFTP1TransactionStop(Sender: TObject);
begin
StatusBar1.SimpleText := 'Data Transfer Complete';
end;
procedure TForm1.NMFTP1HostResolved(Sender: TComponent);
begin
StatusBar1.SimpleText := 'Host resolved';
end;
procedure TForm1.NMFTP1InvalidHost(var handled: Boolean);
begin
ShowMessage('Invalid Host');
end;
procedure TForm1.NMFTP1PacketSent(Sender: TObject);
begin
StatusBar1.SimpleText := IntToStr(NMFTP1.BytesSent)+' of '+IntToStr(NMFTP1.BytesTotal);
end;
procedure TForm1.NMFTP1TransactionStart(Sender: TObject);
begin
StatusBar1.SimpleText := 'Beginning Data Transfer';
end;
procedure TForm1.NMFTP1Disconnect(Sender: TObject);
begin
If StatusBar1 <> nil then
StatusBar1.SimpleText := 'Disconnected';
end;
procedure TForm1.NMFTP1Error(Sender: TComponent; Errno: Word;
Errmsg: String);
begin
ShowMessage('Error '+IntToStr(Errno)+': '+Errmsg);
end;
procedure TForm1.NMFTP1Status(Sender: TComponent; Status: String);
begin
// If StatusBar1 <> nil then
// StatusBar1.SimpleText := status;
end;
procedure TForm1.Button18Click(Sender: TObject);
begin
NMFTP1.Rename(Edit8.Text,Edit9.Text);
end;
procedure TForm1.NMFTP1UnSupportedFunction(Trans_Type: TCmdType);
begin
Case Trans_Type of
cmdChangeDir: ShowMessage('ChangeDir unsupported');
cmdMakeDir: ShowMessage('MakeDir unsupported');
cmdDelete: ShowMessage('Delete unsupported');
cmdRemoveDir: ShowMessage('RemoveDir unsupported');
cmdList: ShowMessage('List unsupported');
cmdRename: ShowMessage('Rename unsupported');
cmdUpRestore: ShowMessage('UploadRestore unsupported');
cmdDownRestore: ShowMessage('DownloadRestore unsupported');
cmdDownload: ShowMessage('Download unsupported');
cmdUpload: ShowMessage('Upload unsupported');
cmdAppend: ShowMessage('UploadAppend unsupported');
cmdReInit: ShowMessage('ReInit unsupported');
cmdAllocate: ShowMessage('Allocate unsupported');
cmdNList: ShowMessage('NList unsupported');
cmdDoCommand: ShowMessage('DoCommand unsupported');
end;
end;
procedure TForm1.NMFTP1ConnectionFailed(Sender: TObject);
begin
ShowMessage('Connection Failed');
end;
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
NMFTP1.Abort;
end;
end.