본문 바로가기
C & C++/MFC Network

간단한 FTP 프로그램

by izen8 2013. 11. 14.
반응형

원본 출처 : 여기 여기




FtpEx.zip




가끔씩 간단한 업데이트 프로그램을 작성할때 FTP를 이용하곤 하는데...

 

막상 WinInet FTP API를 이용해서 개발을 하다보면 손이 많이갑니다. 특히 UTF8 인코딩 문제는 상당히 귀찮습니다(어떤서버(알FTP)는 UTF8을 지원하지 않는 반면 또 어떤 서버(파일질라)는 UTF8만을 지원하기도 하죠)

 

또 컴파일 환경(유니코드, 멀티바이트)에따라 제대로 동작하지 않는 경우도 있구요...

그래서 이참에 차라리 범용적으로 쓸 수 있고 기능성도 있는 간단한 클래스를 하나 만들어보자는 생각에 시간을 들여 아래와 같은 CSimpleFfp를 만들고 간단한 예제프로그램을  작성하였습니다. WinInet FTP Wrapper Class 정도 될 것 같군요.

 

테스트하려면 CFtpExDlg.cpp파일의 제일 상단

FTP_IP, FTP_ID, FTP_PASSWD, FTP_PORT 를 자신의 상황에 맞게 수정하면 됩니다.

 

소스를 작성하면서 아쉬웠던 점은 IIS FTP에서는 이어받기/올리기가 안된다는 점입니다.. 개인적인 생각에 이어받기/이어올리기전에 Port Command를 해야 할 것은데..그렇게 하려면 현재 FTP접속된 WinInet 소켓의 Port를 알아야 합니다. 그런데 MSDN에는 FTP 서버 접속에 성공한 경우 CallBack으로 INTERNET_STATUS_CONNECTED_TO_SERVER으로 SockAddr 포인터가 넘어온다고 되어 있습니다만... 실제로 해보니 정상적으로 넘어오질 않는 것 같습니다...(제가 잘 못 했을 수도 있죠 ^^;)결국 접속된 Port를 알지못해 IIS FTP에서 이어받기/올리기 테스트는 실패했습니다.

 

그러나 다행이도 IIS를 제외한 파일질라, Serve-U, 알FTP 등 대부분의 FTP서버는 이어받기/이어올리기가 가능합니다...

 

본 클래스의 주요기능이라면

 1. 함수하나로 하위 디렉토리를 포함한 파일 업로드/다운로드(개별 파일전송도 지원)

 2. 이어받기/올리기 지원

 3. 파일전송에 대한 진행바

 4. UTF-8, Passive/Active 모드 지원

 

그 밖에 FTP 클라이언트 프로그램을 만드는데 필요한 디렉토리생성(하위디렉토리), 서버쪽 파일크기 구하기 등의 대부분의 기능이 포함되어 있습니다.

 

제 생각에 아마도 WinInet FTP API로 클라이언트를 구현하는 중에 막히는 부분이 있다면

이 소스가 대부분 해결 해주지않을까 생각합니다...

 

 다음은 클래스의 주요 함수들입니다

 

     //로그인
    BOOL Login(CString strIP, CString strID=_T("anonymous"), CString strPasswd=_T(""),
        UINT nPort = INTERNET_DEFAULT_FTP_PORT, HWND hCallWnd = NULL, BOOL bUtf8 = TRUE, BOOL bPassive = FALSE);
    //로그아웃
    void LogOut();
    //FTP서버에 연결되어있으면 TRUE, 아니면 FALSE
    BOOL IsConnected();
    //파일만 다운로드
    BOOL DownloadFile(CString strRemoteFilePath, CString strLocalFilePath, BOOL bResume = FALSE);
    //하위 디렉토리까지 포함하여 다운로드
    BOOL DownloadWithSubDir(CString strRemoteDir, CString strLocalDir, BOOL bResume = FALSE);
    //파일만 업로드
    BOOL UploadFile(CString strLocalFilePath, CString strRemoteFilePath, BOOL bResume = FALSE);
    //하위 디렉토리 포함 업로드
    BOOL UploadWithSubDir(CString strLocalDir, CString strRemoteDir, BOOL bResume = FALSE);
    //FTP서버에 디렉토리를 생성(이때 서버에 없는 하위 디렉토리는 자동 생성한다)
    int CreateRemoteDir(CString strRemoteDir);
    //FTP서버 파일 또는 디렉토리 이름변경
    BOOL RenameRemoteFile(CString strRemoteOldPath, CString strRemoteNewPath);
    //FTP서버의 하위디렉토리 포함 삭제
    BOOL DeleteRemoteDir(CString strRemoteDir);
    //FTP서버의 파일 삭제
    BOOL DeleteRemoteFile(CString strRemoteFilePath);
    //FTP서버 현재 디렉토리 변경
    BOOL SetRemoteDirectory(CString strRemoteDir);
    //FTP서버의 현재 디렉토리 경로를 구함
    BOOL GetRemoteDirectory(__out CString& strRemoteDir);
    //FTP서버의 파일 크기를 구함(성공 TRUE, 실패 FALSE)
    BOOL GetRemoteFileSize(__in CString strRemoteFilePath, __out UINT64& nRemoteFileSize);
    //FTP서버에 특정 디렉토리가 있는지 확인. FTP서버에 디렉토리가 존재하면 1, 오류인경우 -1, 없으면 0
    int FindRemoteDir(CString strRemoteDir);
    //FTP서버에 특정 파일이 있는지 확인. FTP서버에 파일이 존재하면 존재하면 1, 오류인경우 -1, 없으면 0
    int FindRemoteFile(CString strRemoteFilePath);
    //하위 디렉토리 포함한 파일목록(디렉토리+파일)을 구함
    BOOL GetRemoteFileListWithSubDir(__in CString strRemoteDir, __out FILE_LIST& file_list);
    //FTP의 디렉토리 파일목록(디렉토리+파일)을 구함. 하위디렉토리 미포함
    BOOL GetRemoteFileList(__in CString strRemoteDir, __out FILE_LIST& file_list);

 

 

※ 2010. 5. 23 : ① 함수명을 일관성 있도록 변경(SetCurrentDirctory -> SetRemoteDirectory)

                       ② 오타 함수명 수정(UploadWidthSubDir -> UploadWithSubDir)

                       ③ 수천개의 파일 Upload 중에 사용자가 강제로 중지시킨경우 멈추는 문제 수정

반응형

댓글