C++のWINAPIアプリケーションです。
非同期(WININET_API_FLAG_ASYNC)で接続したFTPセッションで、
FtpFileGet()でファイルをダウンロードしようとしています。
そこで、ダウンロード終了の検知ができずに困っております
InternetSetStatusCallback()で指定するコールバック関数で、
1 : INTERNET_STATUS_HANDLE_CREATED
2 : INTERNET_STATUS_RESPONSE_RECEIVEDでプログレス
3 : INTERNET_STATUS_REQUEST_COMPLETE
の順番かと予想していましたが、実際は1.で止まっています。
ファイルはダウンロードされて中身も正しいようです。
CREATEDを以て完了と判断してよいものか、
名前からするとそうではない気もするため悩んでいます。
本来はどの順番で来るものか、
ドキュメントも調べてみたのですが見つけることができませんでした。
セオリーとしてダウンロード完了をどのように判断すればよいか、
ご存じの方がいらっしゃいましたらご教授頂けないでしょうか
現状の、接続からコールバックまわりのコードをシンプルにしたものです。
実際にはダウンロード前に一覧取得していますのでファイルを次々とダウンロードする処理となります。
C++
1HINTERNET hnet = NULL; 2HINTERNET hftp = NULL; 3u32 dlsize = 100; 4u32 dlsize_cur = 0; 5 6void CALLBACK ftp_callback 7( 8 HINTERNET hnet, 9 DWORD dw_context, 10 DWORD dw_status, 11 LPVOID status_info, 12 DWORD status_info_len 13){ 14 switch( dw_status ) 15 { 16 case INTERNET_STATUS_HANDLE_CREATED: 17 { 18 if( app_status == 接続中 ) 19 { 20 LPINTERNET_ASYNC_RESULT result = (LPINTERNET_ASYNC_RESULT) status_info; 21 hftp = (HINTERNET) result->dwResult; 22 } 23 break; 24 } 25 case INTERNET_STATUS_REQUEST_COMPLETE: 26 { 27 if( app_status == 接続中 ) 28 { 29 // ※ここには来る 30 download_core(); 31 } 32 break; 33 } 34 case INTERNET_STATUS_RESPONSE_RECEIVED: 35 { 36 // ※ここに来ない 37 if( app_status == ダウンロード中 ) 38 { 39 LPDWORD bytes = (LPDWORD)status_info; 40 if( dlsize < *bytes ) dlsize = *bytes; 41 42 if( dlsize >= dlsize_cur ) 43 { 44 // ファイルのサイズ分ダウンロードされたので、 45 // ダウンロード完了とする。 46 // ...次のファイルダウンロード処理へ... 47 } 48 } 49 break; 50 } 51 } 52} 53 54// ダウンロード指示 55void download() 56{ 57 hnet = InternetOpen( 58 "ftp_client", 59 INTERNET_OPEN_TYPE_DIRECT, 60 NULL, 61 NULL, 62 WININET_API_FLAG_ASYNC 63 ); 64 if( hnet==NULL ) return エラー; 65 66 // コールバック登録 67 InternetSetStatusCallback( 68 hnet, 69 (INTERNET_STATUS_CALLBACK)&ftp_callback 70 ); 71 72 hftp = InternetConnect 73 ( 74 hnet, 75 "xx.xx.xx.xx", 76 INTERNET_DEFAULT_FTP_PORT, 77 NULL, 78 NULL, 79 INTERNET_SERVICE_FTP, 80 NULL, 81 (DWORD)&context 82 ); 83 if( hftp != NULL ) 84 { 85 download_core(); 86 } 87 else if( GetLastError()==ERROR_IO_PENDING ) app_status = 接続中 88 else { return 接続エラー } 89} 90 91void download_core() 92{ 93 if( ! hftp ) return; 94 if( FtpGetFile( 95 hftp, 96 "filename.txt", 97 "C:\\test\\test.txt", 98 false, 99 FILE_ATTRIBUTE_NORMAL, 100 FTP_TRANSFER_TYPE_BINARY, 101 NULL 102 ) == FALSE ){ 103 エラー処理 104 } 105 app_status = ダウンロード中 106 107 // ※ここまでは来る 108 // 上記メソッド実行時に、INTERNET_STATUS_HANDLE_CREATED 109 // を受け取り、ファイルも出来上がっているが、 110 // その他のイベントが来ない 111}