FTP 세션

WinINet을 사용하면 애플리케이션이 ftp 서버의 디렉터리와 파일을 탐색하고 조작할 수 있습니다. CERN 프록시는 FTP를 지원하지 않으므로 CERN 프록시를 단독으로 사용하는 애플리케이션은 InternetOpenUrl 함수를 사용해야 합니다. InternetOpenUrl을 사용하는 방법에 대한 자세한 내용은 URL 직접 액세스를 참조하세요.

FTP 세션을 시작하려면 InternetConnect 를 사용하여 세션 핸들을 만듭니다.

WinINet을 사용하면 FTP 서버에서 다음 작업을 수행할 수 있습니다.

  • 디렉터리 간을 탐색합니다.
  • 디렉터리를 열거, 만들기, 제거 및 이름을 바꿉니다.
  • 파일 이름 바꾸기, 업로드, 다운로드 및 삭제

탐색은 FtpGetCurrentDirectoryFtpSetCurrentDirectory 함수에서 제공됩니다. 이러한 함수는 InternetConnect 에 대한 이전 호출에서 만든 세션 핸들을 활용하여 애플리케이션이 현재 있는 디렉터리를 확인하거나 다른 하위 디렉터리로 변경합니다.

디렉터리 열거형은 FtpFindFirstFileInternetFindNextFile 함수를 사용하여 수행됩니다. FtpFindFirstFileInternetConnect 에서 만든 세션 핸들을 사용하여 지정된 검색 조건과 일치하는 첫 번째 파일을 찾고 핸들을 반환하여 디렉터리 열거를 계속합니다. InternetFindNextFileFtpFindFirstFile 에서 반환된 핸들을 사용하여 원래 검색 조건과 일치하는 다음 파일을 반환합니다. 애플리케이션은 디렉터리에 더 이상 파일이 남아 있지 않을 때까지 InternetFindNextFile 을 계속 호출해야 합니다.

FtpCreateDirectory 함수를 사용하여 새 디렉터리를 만듭니다. 이 함수는 InternetConnect 에서 만든 세션 핸들을 사용하고 함수에 전달된 문자열로 지정된 디렉터리를 만듭니다. 문자열에는 현재 디렉터리를 기준으로 하는 디렉터리 이름 또는 정규화된 디렉터리 경로가 포함될 수 있습니다.

파일 또는 디렉터리 이름을 바꾸려면 애플리케이션에서 FtpRenameFile을 호출할 수 있습니다. 이 함수는 원래 이름을 함수에 전달된 새 이름으로 바꿉니다. 파일 또는 디렉터리의 이름은 현재 디렉터리 또는 정규화된 이름을 기준으로 할 수 있습니다.

FTP 서버에 파일을 업로드하거나 배치하기 위해 애플리케이션은 FtpPutFile 또는 FtpOpenFile ( InternetWriteFile과 함께)을 사용할 수 있습니다. 파일이 이미 로컬에 있는 경우 FtpPutFile을 사용할 수 있으며 FTP 서버의 파일에 데이터를 기록해야 하는 경우 FtpOpenFileInternetWriteFile을 사용할 수 있습니다.

파일을 다운로드하거나 가져오기 위해 애플리케이션은 FtpGetFile 또는 FtpOpenFile ( InternetReadFile 사용)을 사용할 수 있습니다. FtpGetFile 은 FTP 서버에서 파일을 검색하고 로컬로 저장하는 데 사용되며, FtpOpenFileInternetReadFile 을 사용하여 다운로드한 정보의 위치를 제어할 수 있습니다(예: 애플리케이션이 편집 상자에 정보를 표시할 수 있음).

FtpDeleteFile 함수를 사용하여 FTP 서버에서 파일을 삭제합니다. 이 함수는 FTP 서버에서 현재 디렉터리 또는 정규화된 파일 이름을 기준으로 하는 파일 이름을 제거합니다. FtpDeleteFile 에는 InternetConnect에서 반환된 세션 핸들이 필요합니다.

FTP 함수 핸들

제대로 작동하려면 FTP 함수에 특정 유형의 HINTERNET 핸들이 필요합니다. 이러한 핸들은 InternetOpen에서 만든 루트 핸들부터 특정 순서로 만들어야 합니다. InternetConnect 는 FTP 세션 핸들을 만들 수 있습니다.

다음 다이어그램은 InternetConnect에서 반환된 FTP 세션 핸들에 종속된 함수를 보여 줍니다. 음영 처리된 상자는 HINTERNET 핸들을 반환하는 함수를 나타내고 일반 상자는 해당 핸들이 의존하는 함수에서 만든 HINTERNET 핸들을 사용하는 함수를 나타냅니다.

internetconnect에서 반환된 ftp 세션 핸들에 종속된 ftp 함수

다음 다이어그램에서는 HINTERNET 핸들을 반환하는 두 함수와 해당 핸들에 종속된 함수를 보여 줍니다. 음영 처리된 상자는 HINTERNET 핸들을 반환하는 함수를 나타내고 일반 상자는 해당 핸들이 의존하는 함수에서 만든 HINTERNET 핸들을 사용하는 함수를 나타냅니다.

hinternet 핸들을 반환하는 ftp 함수

자세한 내용은 HINTERNET 핸들을 참조하세요.

FTP 세션에 WinINet 함수 사용

FTP 세션 중에는 다음 함수가 사용됩니다. 이러한 함수는 CERN 프록시에서 인식되지 않습니다. CERN 프록시를 통해 작동해야 하는 애플리케이션은 InternetOpenUrl 을 사용하고 리소스에 직접 액세스해야 합니다. 직접 리소스 액세스에 대한 자세한 내용은 URL 직접 액세스를 참조하세요.

함수 Description
FtpCreateDirectory 서버에 새 디렉터리를 만듭니다. 이 함수에는 InternetConnect에서 만든 핸들이 필요합니다.
FtpDeleteFile 서버에서 파일을 삭제합니다. 이 함수에는 InternetConnect에서 만든 핸들이 필요합니다.
FtpFindFirstFile 현재 디렉터리에서 파일 열거 또는 파일 검색을 시작합니다. 이 함수에는 InternetConnect에서 만든 핸들이 필요합니다.
FtpGetCurrentDirectory 서버에서 클라이언트의 현재 디렉터리를 반환합니다. 이 함수에는 InternetConnect에서 만든 핸들이 필요합니다.
FtpGetFile 서버에서 파일을 검색합니다. 이 함수에는 InternetConnect에서 만든 핸들이 필요합니다.
FtpOpenFile 읽기 또는 쓰기를 위해 서버의 파일에 대한 액세스를 시작합니다. 이 함수에는 InternetConnect에서 만든 핸들이 필요합니다.
FtpPutFile 서버에 파일을 씁니다. 이 함수에는 InternetConnect에서 만든 핸들이 필요합니다.
FtpRemoveDirectory 서버에서 디렉터리를 삭제합니다. 이 함수에는 InternetConnect에서 만든 핸들이 필요합니다.
FtpRenameFile 서버의 파일 이름을 바꿉니다. 이 함수에는 InternetConnect에서 만든 핸들이 필요합니다.
FtpSetCurrentDirectory 서버에서 클라이언트의 현재 디렉터리를 변경합니다. 이 함수에는 InternetConnect에서 만든 핸들이 필요합니다.
InternetWriteFile 서버의 열린 파일에 데이터를 씁니다. 이 함수에는 FtpOpenFile에서 만든 핸들이 필요합니다.

 

FTP 세션 시작

애플리케이션은 InternetOpen에서 만든 핸들에서 InternetConnect를 호출하여 FTP 세션을 설정합니다. InternetConnect 에는 서버 이름, 포트 번호, 사용자 이름, 암호 및 서비스 유형(INTERNET_SERVICE_FTP 설정해야 합니다)이 필요합니다. 수동 FTP 의미 체계의 경우 애플리케이션은 INTERNET_FLAG_PASSIVE 플래그도 설정해야 합니다.

INTERNET_DEFAULT_FTP_PORT 및 INTERNET_INVALID_PORT_NUMBER 값을 포트 번호에 사용할 수 있습니다. INTERNET_DEFAULT_FTP_PORT 기본 FTP 포트를 사용하지만 서비스 유형은 여전히 설정해야 합니다. INTERNET_INVALID_PORT_NUMBER 표시된 서비스 형식의 기본값을 사용합니다.

사용자 이름 및 암호 값은 NULL로 설정할 수 있습니다. 두 값이 모두 NULL로 설정된 경우 InternetConnect 는 사용자 이름 및 암호에 대한 사용자의 이메일 주소에 "익명"을 사용합니다. 암호만 NULL로 설정된 경우 InternetConnect 에 전달된 사용자 이름이 사용자 이름에 사용되고 암호에 빈 문자열이 사용됩니다. 두 값이 모두 NULL이 아니면 InternetConnect 에 지정된 사용자 이름과 암호가 사용됩니다.

디렉터리 열거

FTP 서버에서 디렉터리를 열거하려면 FtpFindFirstFile에서 핸들을 생성해야 합니다. 이 핸들은 InternetConnect에서 만든 세션 핸들의 분기입니다. FtpFindFirstFile 은 서버에서 첫 번째 파일 또는 디렉터리를 찾아 WIN32_FIND_DATA 구조로 반환합니다. ERROR_NO_MORE_FILES 반환될 때까지 InternetFindNextFile을 사용합니다. 이 메서드는 서버에서 모든 후속 파일 및 디렉터리를 찾습니다. InternetFindNextFile에 대한 자세한 내용은 다음 파일 찾기를 참조하세요.

FtpFindFirstFile 또는 InternetFindNextFile에서 검색한 파일이 디렉터리인지 확인하려면 WIN32_FIND_DATA 구조체의 dwFileAttributes 멤버를 검사 FILE_ATTRIBUTE_DIRECTORY.

애플리케이션이 FTP 서버에서 변경하거나 FTP 서버가 자주 변경되는 경우 ftpFindFirstFile에서 INTERNET_FLAG_NO_CACHE_WRITEINTERNET_FLAG_RELOAD 플래그를 설정해야 합니다. 이러한 플래그는 FTP 서버에서 검색되는 디렉터리 정보가 최신인지 확인합니다.

애플리케이션이 디렉터리 열거를 완료한 후 애플리케이션은 FtpFindFirstFile에서 만든 핸들에서 InternetCloseHandle을 호출해야 합니다. 해당 핸들을 닫을 때까지 애플리케이션은 InternetConnect에서 만든 세션 핸들에서 FtpFindFirstFile을 다시 호출할 수 없습니다. 동일한 함수에 대한 이전 호출을 닫기 전에 동일한 세션 핸들에서 FtpFindFirstFile 을 호출하면 함수가 실패하고 ERROR_FTP_TRANSFER_IN_PROGRESS 반환됩니다.

다음 예제에서는 FTP 디렉터리의 내용을 목록 상자 컨트롤에 열거합니다. hConnection 매개 변수는 FTP 세션을 설정한 후 InternetConnect 함수에서 반환하는 핸들입니다. 이 예제에서 참조하는 InternetErrorOut 함수에 대한 샘플 소스 코드는 오류 처리항목에서 찾을 수 있습니다.

#include <windows.h>
#include <strsafe.h>
#include <wininet.h>

#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "user32.lib")

#define  FTP_FUNCTIONS_BUFFER_SIZE          MAX_PATH+8

BOOL WINAPI DisplayFtpDir(
                           HWND hDlg,
                           HINTERNET hConnection,
                           DWORD dwFindFlags,
                           int nListBoxId )
{
  WIN32_FIND_DATA dirInfo;
  HINTERNET       hFind;
  DWORD           dwError;
  BOOL            retVal = FALSE;
  TCHAR           szMsgBuffer[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR           szFName[FTP_FUNCTIONS_BUFFER_SIZE];
  
  SendDlgItemMessage( hDlg, nListBoxId, LB_RESETCONTENT, 0, 0 );
  hFind = FtpFindFirstFile( hConnection, TEXT( "*.*" ), 
                            &dirInfo, dwFindFlags, 0 );
  if ( hFind == NULL )
  {
    dwError = GetLastError( );
    if( dwError == ERROR_NO_MORE_FILES )
    {
      StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
        TEXT( "No files found at FTP location specified." ) );
      retVal = TRUE;
      goto DisplayDirError_1;
    }
    StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
      TEXT( "FtpFindFirstFile failed." ) );
    goto DisplayDirError_1;
  }

  do
  {
    if( FAILED( StringCchCopy( szFName, FTP_FUNCTIONS_BUFFER_SIZE,
                  dirInfo.cFileName ) ) ||
        ( ( dirInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) &&
        ( FAILED( StringCchCat( szFName, FTP_FUNCTIONS_BUFFER_SIZE,
         TEXT( " <DIR> " ) ) ) ) ) )
    {
      StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
        TEXT( "Failed to copy a file or directory name." ) );
      retVal = FALSE;
      goto DisplayDirError_2;
    }
    SendDlgItemMessage( hDlg, nListBoxId, LB_ADDSTRING, 
                        0, (LPARAM) szFName );
  } while( InternetFindNextFile( hFind, (LPVOID) &dirInfo ) );

  if( ( dwError = GetLastError( ) ) == ERROR_NO_MORE_FILES )
  {
    InternetCloseHandle(hFind);
    return( TRUE );
  }
  StringCchCopy( szMsgBuffer, FTP_FUNCTIONS_BUFFER_SIZE,
    TEXT( "FtpFindNextFile failed." ) );

DisplayDirError_2:
  InternetCloseHandle( hFind );
DisplayDirError_1:
  MessageBox( hDlg,
    (LPCTSTR) szMsgBuffer,
    TEXT( "DisplayFtpDir( ) Problem" ),
    MB_OK | MB_ICONERROR );
  return( retVal );
}

FtpGetCurrentDirectoryFtpSetCurrentDirectory 함수는 디렉터리 탐색을 처리합니다.

FtpGetCurrentDirectory 는 FTP 서버에서 애플리케이션의 현재 디렉터리를 반환합니다. FTP 서버의 루트 디렉터리에서 디렉터리 경로가 포함됩니다.

FtpSetCurrentDirectory 는 서버의 작업 디렉터리를 변경합니다. FtpSetCurrentDirectory에 전달된 디렉터리 정보는 현재 디렉터리를 기준으로 부분적으로 또는 정규화된 경로 이름일 수 있습니다. 예를 들어 애플리케이션이 현재 디렉터리 "public/info"에 있고 경로가 "ftp/example"인 경우 FtpSetCurrentDirectory 는 현재 디렉터리를 "public/info/ftp/example"로 변경합니다.

다음 예제에서는 InternetConnect에서 반환되는 FTP 세션 핸들 hConnection을 사용합니다. 새 디렉터리 이름은 idC가 nDirNameId 매개 변수에 전달되는 부모 대화 상자의 편집 상자에서 가져옵니다. 디렉터리를 변경하기 전에 함수는 현재 디렉터리를 검색하여 동일한 편집 상자에 저장합니다. 끝에 호출된 DisplayFtpDir 함수에 대한 souce 코드가 위에 나열되어 있습니다.

BOOL WINAPI ChangeFtpDir( HWND hDlg, 
                          HINTERNET hConnection,
                          int nDirNameId, 
                          int nListBoxId )
{
  DWORD dwSize;
  TCHAR szNewDirName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szOldDirName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR* szFailedFunctionName;

  dwSize = FTP_FUNCTIONS_BUFFER_SIZE;

  if( !GetDlgItemText( hDlg, nDirNameId, szNewDirName, dwSize ) )
  {
    szFailedFunctionName = TEXT( "GetDlgItemText" );
    goto ChangeFtpDirError;
  }

  if ( !FtpGetCurrentDirectory( hConnection, szOldDirName, &dwSize ))
  {
    szFailedFunctionName = TEXT( "FtpGetCurrentDirectory" );
    goto ChangeFtpDirError;
  }

  if( !SetDlgItemText( hDlg, nDirNameId, szOldDirName ) )
  {
    szFailedFunctionName = TEXT( "SetDlgItemText" );
    goto ChangeFtpDirError;
  }

  if( !FtpSetCurrentDirectory( hConnection, szNewDirName ) )
  {
    szFailedFunctionName = TEXT( "FtpSetCurrentDirectory" );
    goto ChangeFtpDirError;
  }
  return( DisplayFtpDir( hDlg, hConnection, 0, nListBoxId ) );

ChangeFtpDirError:
  InternetErrorOut( hDlg, GetLastError( ), szFailedFunctionName );
  DisplayFtpDir( hDlg, hConnection, INTERNET_FLAG_RELOAD, nListBoxId);
  return( FALSE );
}

FTP 서버에서 디렉터리 조작

WinINet은 애플리케이션에 필요한 권한이 있는 FTP 서버에서 디렉터리를 만들고 제거하는 기능을 제공합니다. 애플리케이션이 특정 사용자 이름 및 암호를 사용하여 서버에 로그온해야 하는 경우 FTP 세션 핸들을 만들 때 InternetConnect 에서 값을 사용할 수 있습니다.

FtpCreateDirectory 함수는 유효한 FTP 세션 핸들과 현재 디렉터리에 상대적인 정규화된 경로 또는 이름을 포함하고 FTP 서버에 디렉터리를 만드는 null로 끝나는 문자열을 사용합니다.

다음 예제에서는 FtpCreateDirectory에 대한 두 개의 별도 호출을 보여줍니다. 두 예제에서 hFtpSession은 InternetConnect 함수에서 만든 세션 핸들이며 루트 디렉터리는 현재 디렉터리입니다.

/* Creates the directory "test" in the current (root) directory. */
FtpCreateDirectory( hFtpSession, "test" );

/* Creates the directory "example" in the test directory. */
FtpCreateDirectory( hFtpSession, "\\test\\example" );

FtpRemoveDirectory 함수는 세션 핸들과 현재 디렉터리에 상대적인 정규화된 경로 또는 이름을 포함하는 null로 끝나는 문자열을 사용하고 FTP 서버에서 해당 디렉터리를 제거합니다.

다음 예제에서는 FtpRemoveDirectory에 대한 두 가지 샘플 호출을 보여줍니다. 두 호출 모두에서 hFtpSession은 InternetConnect 함수에서 만든 세션 핸들이며 루트 디렉터리는 현재 디렉터리입니다. 루트 디렉터리에는 "test"라는 디렉터리와 "test" 디렉터리에 "example"라는 디렉터리가 있습니다.

/* Removes the "example" directory (plus any files/directories it contains) from the "test" directory. */
FtpRemoveDirectory(hFtpSession,"\\test\\example");

/* Removes the "test" directory (plus any files/directories it contains) from the root directory. */
FtpRemoveDirectory(hFtpSession, "test");
FtpRemoveDirectory(hFtpSession,TEXT("\\test\\example"));
/* Removes the "example" directory and any files or 
directories contained in it from the "test" directory. */

FtpRemoveDirectory(hFtpSession, TEXT("test"));
/* Removes the "test" directory and any files or 
directories contained in it from the root directory. */

다음 예제에서는 FTP 서버에 새 디렉터리를 만듭니다. 새 디렉터리 이름은 idC가 nDirNameId 매개 변수에 전달되는 부모 대화 상자의 편집 상자에서 가져옵니다. hConnection 핸들은 FTP 세션을 설정한 후 InternetConnect에서 만들었습니다. 끝에 호출된 DisplayFtpDir 함수의 소스 코드가 위에 나열되어 있습니다.

BOOL WINAPI CreateFtpDir( HWND hDlg, HINTERNET hConnection,
                          int nDirNameId, int nListBoxId )
{
  TCHAR szNewDirName[FTP_FUNCTIONS_BUFFER_SIZE];

  if( !GetDlgItemText( hDlg, nDirNameId, 
                       szNewDirName, 
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT( "Error: Directory Name Must Be Specified" ),
                TEXT( "Create FTP Directory" ), 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpCreateDirectory( hConnection, szNewDirName ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), 
                      TEXT( "FtpCreateDirectory" ) );
    return( FALSE );
  }

  return( DisplayFtpDir( hDlg, hConnection, 
                         INTERNET_FLAG_RELOAD, 
                         nListBoxId ) );
}

다음 예제에서는 FTP 서버에서 디렉터리를 삭제합니다. 삭제할 디렉터리의 이름은 IDC가 nDirNameId 매개 변수에 전달되는 부모 대화 상자의 편집 상자에서 가져옵니다. hConnection 핸들은 FTP 세션을 설정한 후 InternetConnect에서 만들었습니다. 끝에 호출된 DisplayFtpDir 함수의 소스 코드가 위에 나열되어 있습니다.

BOOL WINAPI RemoveFtpDir( HWND hDlg, HINTERNET hConnection,
                          int nDirNameId, int nListBoxId )
{
  TCHAR szDelDirName[FTP_FUNCTIONS_BUFFER_SIZE];

  if( !GetDlgItemText( hDlg, nDirNameId, szDelDirName, 
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT( "Error: Directory Name Must Be Specified" ),
                TEXT( "Remove FTP Directory" ), 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpRemoveDirectory( hConnection, szDelDirName ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), 
                      TEXT( "FtpRemoveDirectory" ) );
    return( FALSE );
  }

  return( DisplayFtpDir( hDlg, hConnection, 
                         INTERNET_FLAG_RELOAD, nListBoxId ) );
}

FTP 서버에서 파일 가져오기

FTP 서버에서 파일을 검색하는 방법에는 다음 세 가지가 있습니다.

InternetReadFile 함수 사용에 대한 자세한 내용은 파일 읽기를 참조하세요.

파일의 URL을 사용할 수 있는 경우 애플리케이션은 InternetOpenUrl 을 호출하여 해당 URL에 연결한 다음 InternetReadFile 을 사용하여 파일 다운로드를 제어할 수 있습니다. 이렇게 하면 애플리케이션이 다운로드를 보다 엄격하게 제어할 수 있으며 FTP 서버에서 다른 작업을 수행할 필요가 없는 경우에 적합합니다. 리소스에 직접 액세스하는 방법에 대한 자세한 내용은 URL 직접 액세스를 참조하세요.

애플리케이션이 InternetConnect를 사용하여 서버에 FTP 세션 핸들을 설정한 경우 애플리케이션은 기존 파일 이름과 로컬로 저장된 파일의 새 이름으로 FtpOpenFile 을 호출할 수 있습니다. 그러면 애플리케이션에서 InternetReadFile 을 사용하여 파일을 다운로드할 수 있습니다. 이렇게 하면 애플리케이션이 다운로드를 보다 엄격하게 제어하고 FTP 서버에 대한 연결을 유지하므로 더 많은 명령을 실행할 수 있습니다.

애플리케이션이 다운로드를 엄격하게 제어할 필요가 없는 경우 애플리케이션은 FTP 세션 핸들, 원격 파일 이름 및 로컬 파일 이름과 함께 FtpGetFile 을 사용하여 파일을 검색할 수 있습니다. FtpGetFile은 FTP 서버에서 파일을 읽고 로컬로 저장하는 것과 관련된 모든 부기 및 오버헤드를 수행합니다.

다음 예제에서는 FTP 서버에서 파일을 검색하고 로컬로 저장합니다. FTP 서버의 파일 이름은 nFtpFileNameId 매개 변수에 IDC가 전달되는 부모 대화 상자의 편집 상자에서 가져오고, 파일이 저장되는 로컬 이름은 idC가 nLocalFileNameId 매개 변수에 전달되는 편집 상자에서 가져옵니다. hConnection 핸들은 FTP 세션을 설정한 후 InternetConnect에서 만들었습니다.

BOOL WINAPI GetFtpFile( HWND hDlg, HINTERNET hConnection,
                        int nFtpFileNameId, int nLocalFileNameId )
{
  TCHAR szFtpFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szLocalFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  DWORD dwTransferType;
  TCHAR szBoxTitle[] = TEXT( "Download FTP File" );
  TCHAR szAsciiQuery[] =
    TEXT("Do you want to download as ASCII text?(Default is binary)");
  TCHAR szAsciiDone[] = 
    TEXT( "ASCII Transfer completed successfully..." );
  TCHAR szBinaryDone[] = 
    TEXT( "Binary Transfer completed successfully..." );

  if( !GetDlgItemText( hDlg, nFtpFileNameId, szFtpFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) ||
      !GetDlgItemText( hDlg, nLocalFileNameId, szLocalFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT( "Target File or Destination File Missing" ),
                szBoxTitle, 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  dwTransferType = ( MessageBox( hDlg, 
                                 szAsciiQuery, 
                                 szBoxTitle, 
                                 MB_YESNO ) == IDYES ) ?
                   FTP_TRANSFER_TYPE_ASCII : FTP_TRANSFER_TYPE_BINARY;
  dwTransferType |= INTERNET_FLAG_RELOAD;

  if( !FtpGetFile( hConnection, szFtpFileName, szLocalFileName, FALSE,
                   FILE_ATTRIBUTE_NORMAL, dwTransferType, 0 ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), TEXT( "FtpGetFile" ) );
    return( FALSE );
  }

  MessageBox( hDlg,( dwTransferType == 
                      (FTP_TRANSFER_TYPE_ASCII | INTERNET_FLAG_RELOAD)) ?
                      szAsciiDone : szBinaryDone, szBoxTitle, MB_OK );
  return( TRUE );
}

FTP 서버에 파일 배치

FTP 서버에 파일을 배치하는 방법에는 두 가지가 있습니다.

FTP 서버로 데이터를 보내야 하지만 모든 데이터가 포함된 로컬 파일이 없는 애플리케이션은 FtpOpenFile을 사용하여 ftp 서버에서 파일을 만들고 열어야 합니다. 그런 다음, 애플리케이션은 InternetWriteFile 을 사용하여 정보를 파일에 업로드할 수 있습니다.

파일이 이미 로컬에 있는 경우 애플리케이션은 FtpPutFile 을 사용하여 FTP 서버에 파일을 업로드할 수 있습니다. FtpPutFile 은 로컬 파일을 원격 FTP 서버에 업로드하는 것과 관련된 모든 오버헤드를 수행합니다.

다음 예제에서는 FTP 서버에 로컬 파일을 복사합니다. 파일의 로컬 이름은 nLocalFileNameId 매개 변수에 IDC가 전달되는 부모 대화 상자의 편집 상자에서 가져온 것이며, FTP 서버에 파일이 저장되는 이름은 IDC가 nFtpFileNameId 매개 변수에 전달되는 편집 상자에서 가져옵니다. hConnection 핸들은 FTP 세션을 설정한 후 InternetConnect에서 만들었습니다.

BOOL WINAPI PutFtpFile( HWND hDlg, HINTERNET hConnection,
                        int nFtpFileNameId, int nLocalFileNameId )
{
  TCHAR szFtpFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szLocalFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  DWORD dwTransferType;
  TCHAR szBoxTitle[] = TEXT( "Upload FTP File" );
  TCHAR szASCIIQuery[] =
    TEXT("Do you want to upload as ASCII text? (Default is binary)");
  TCHAR szAsciiDone[] = 
    TEXT( "ASCII Transfer completed successfully..." );
  TCHAR szBinaryDone[] = 
    TEXT( "Binary Transfer completed successfully..." );

  if( !GetDlgItemText( hDlg, nFtpFileNameId, szFtpFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) ||
      !GetDlgItemText( hDlg, nLocalFileNameId, szLocalFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, 
                TEXT("Target File or Destination File Missing"),
                szBoxTitle, 
                MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  dwTransferType =
    ( MessageBox( hDlg, 
                  szASCIIQuery, 
                  szBoxTitle, 
                  MB_YESNO ) == IDYES ) ?
    FTP_TRANSFER_TYPE_ASCII : FTP_TRANSFER_TYPE_BINARY;

  if( !FtpPutFile( hConnection, 
                   szLocalFileName, 
                   szFtpFileName, 
                   dwTransferType, 
                   0 ) )
  {
    InternetErrorOut( hDlg, GetLastError( ), TEXT( "FtpGetFile" ) );
    return( FALSE );
  }

  MessageBox( hDlg,
              ( dwTransferType == FTP_TRANSFER_TYPE_ASCII ) ?
                szAsciiDone : szBinaryDone, szBoxTitle, MB_OK );
  return( TRUE );  // Remember to refresh directory listing
}

FTP 서버에서 파일 삭제

FTP 서버에서 파일을 삭제하려면 FtpDeleteFile 함수를 사용합니다. 호출 애플리케이션에는 FTP 서버에서 파일을 삭제하는 데 필요한 권한이 있어야 합니다.

다음 예제에서는 FTP 서버에서 파일을 삭제합니다. 삭제할 파일의 이름은 nFtpFileNameId 매개 변수에 대해 IDC가 전달되는 부모 대화 상자의 편집 상자에서 가져옵니다. hConnection 핸들은 FTP 세션을 설정한 후 InternetConnect에서 만들었습니다. 이 함수는 파일 목록 또는 디렉터리 표시를 새로 고치지 않으므로 호출 프로세스는 성공적으로 삭제될 때 새로 고쳐야 합니다.

BOOL WINAPI DeleteFtpFile( HWND hDlg, HINTERNET hConnection,
                           int nFtpFileNameId )
{
  TCHAR szFtpFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szBoxTitle[] = TEXT( "Delete FTP File" );

  if( !GetDlgItemText( hDlg, nFtpFileNameId, szFtpFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg, TEXT( "File Name Must Be Specified!" ),
                szBoxTitle, MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpDeleteFile( hConnection, szFtpFileName ) )
  {
    InternetErrorOut( hDlg, 
                      GetLastError( ), 
                      TEXT( "FtpDeleteFile" ) );
    return( FALSE );
  }

  MessageBox( hDlg, 
              TEXT( "File has been deleted" ), 
              szBoxTitle, 
              MB_OK );
  return( TRUE );  // Remember to refresh directory listing
}

FTP 서버에서 파일 및 디렉터리 이름 바꾸기

FtpRenameFile 함수를 사용하여 FTP 서버의 파일 및 디렉터리 이름을 바꿀 수 있습니다. FtpRenameFile 은 현재 디렉터리를 기준으로 부분적으로 또는 정규화된 이름을 포함하는 두 개의 null로 끝나는 문자열을 허용합니다. 함수는 첫 번째 문자열로 지정된 파일의 이름을 두 번째 문자열로 지정된 이름으로 변경합니다.

다음 예제에서는 FTP 서버에서 파일 또는 디렉터리의 이름을 바꿉니다. 파일 또는 디렉터리의 현재 이름은 nOldFileNameId 매개 변수에 IDC가 전달되는 부모 대화 상자의 편집 상자에서 가져온 것이며, 새 이름은 idC가 nNewFileNameId 매개 변수에 전달되는 편집 상자에서 가져옵니다. hConnection 핸들은 FTP 세션을 설정한 후 InternetConnect에서 만들었습니다. 이 함수는 파일 목록 또는 디렉터리 표시를 새로 고치지 않으므로 호출 프로세스는 이름을 성공적으로 변경하면 새로 고쳐야 합니다.

BOOL WINAPI RenameFtpFile( HWND hDlg, HINTERNET hConnection,
                           int nOldFileNameId, int nNewFileNameId )
{
  TCHAR szOldFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szNewFileName[FTP_FUNCTIONS_BUFFER_SIZE];
  TCHAR szBoxTitle[] = TEXT( "Rename FTP File" );

  if( !GetDlgItemText( hDlg, nOldFileNameId, szOldFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) ||
      !GetDlgItemText( hDlg, nNewFileNameId, szNewFileName,
                       FTP_FUNCTIONS_BUFFER_SIZE ) )
  {
    MessageBox( hDlg,
        TEXT( "Both the current and new file names must be supplied" ),
        szBoxTitle, 
        MB_OK | MB_ICONERROR );
    return( FALSE );
  }

  if( !FtpRenameFile( hConnection, szOldFileName, szNewFileName ) )
  {
    MessageBox( hDlg,
        TEXT( "FtpRenameFile failed" ),
        szBoxTitle, 
        MB_OK | MB_ICONERROR );
    return( FALSE );
  }
  return( TRUE );  // Remember to refresh directory listing
}

참고

WinINet은 서버 구현을 지원하지 않습니다. 또한 서비스에서 사용하면 안 됩니다. 서버 구현 또는 서비스의 경우 WinHTTP(Microsoft Windows HTTP 서비스)를 사용합니다.