원본 출처 : 여기 여기
가끔씩 간단한 업데이트 프로그램을 작성할때 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 중에 사용자가 강제로 중지시킨경우 멈추는 문제 수정
'C & C++ > MFC Network' 카테고리의 다른 글
시리얼 통신 필수 함수(HexToInteger, HexToFloat, HexToDouble) (0) | 2013.11.14 |
---|---|
[SendMessageCallback] 메시지(Message) 처리 (0) | 2013.11.14 |
포털 사이트 및 웹페이지 자동 로그인 프로그램 (0) | 2013.11.14 |
[Windows IPC] 프로세스간 통신 (0) | 2013.11.14 |
[Web] 하이퍼 링크 (0) | 2011.12.14 |
댓글