동기화 모드로 InternetOpenUrl 함수를 사용하다 보니 블러킹 상태에 대한
조치가 필요해서 InternetSetOption 함수의 Timeout 인자를 설정했지만
안먹더군요... 그래서 인터넷을 뒤진 결과 MS 버그 ㅡㅡ;
결국 MS에서 알려준 방법대로 스레드로 처리하긴 했습니다.
뭐 이건 배보다 배꼽이 더큰 경우라고 할 수 있네요...
#include "windows.h"
#include "wininet.h"
#include "iostream.h"

DWORD WINAPI WorkerFunction( LPVOID ); 
HINTERNET g_hOpen, g_hConnect;

typedef struct 
{
   CHAR* pHost;
   CHAR* pUser;
   CHAR* pPass;
} PARM;

void main()
{
   CHAR    szHost[] = "localhost";
   CHAR    szUser[] = "JoeB";
   CHAR    szPass[] = "test";
   CHAR    szLocalFile[] = "localfile";
   CHAR    szRemoteFile[] = "remotefile";
   DWORD   dwExitCode;
   DWORD   dwTimeout;
   PARM    threadParm;

   g_hOpen = 0;
   if ( !( g_hOpen = InternetOpen ( "FTP sample", 
                                    LOCAL_INTERNET_ACCESS, 
                                    NULL, 
                                    0, 
                                    0 ) ) )
   {         
       cerr << "Error on InternetOpen: " << GetLastError() << endl;
       return ;
   }

   // Create a worker thread 
   HANDLE   hThread; 
   DWORD    dwThreadID;
   threadParm.pHost = szHost;
   threadParm.pUser = szUser;
   threadParm.pPass = szPass;

   hThread = CreateThread(
                 NULL,            // Pointer to thread security attributes 
                 0,               // Initial thread stack size, in bytes 
                 WorkerFunction,  // Pointer to thread function 
                 &threadParm,     // The argument for the new thread
                 0,               // Creation flags 
                 &dwThreadID      // Pointer to returned thread identifier 
             );    

   // Wait for the call to InternetConnect in worker function to complete
   dwTimeout = 5000; // in milliseconds
   if ( WaitForSingleObject ( hThread, dwTimeout ) == WAIT_TIMEOUT )
   {
       cout << "Can not connect to server in " 
            << dwTimeout << " milliseconds" << endl;
       if ( g_hOpen )
InternetCloseHandle ( g_hOpen );
       // Wait until the worker thread exits
       WaitForSingleObject ( hThread, INFINITE );
       cout << "Thread has exited" << endl;
       return ;
   }

   // The state of the specified object (thread) is signaled
   dwExitCode = 0;
   if ( !GetExitCodeThread( hThread, &dwExitCode ) )
   {
       cerr << "Error on GetExitCodeThread: " << GetLastError() << endl;
       return ;
   }

   CloseHandle (hThread);
   if ( dwExitCode )
   // Worker function failed
      return ;

   if ( !FtpGetFile ( g_hConnect, 
                      szRemoteFile,
                      szLocalFile,
                      FALSE,INTERNET_FLAG_RELOAD, 
                      FTP_TRANSFER_TYPE_ASCII,
                      0 ) )
   {
       cerr << "Error on FtpGetFile: " << GetLastError() << endl;
       return ;
   }

   if ( g_hConnect )
       InternetCloseHandle( g_hConnect );
   if ( g_hOpen )
       InternetCloseHandle( g_hOpen );

   return ;
}

/////////////////// WorkerFunction ////////////////////// 
DWORD WINAPI 
WorkerFunction(
   IN LPVOID vThreadParm
)
/*
Purpose:
   Call InternetConnect to establish a FTP session  
Arguments:
   vThreadParm - points to PARM passed to thread
Returns:
   returns 0  
*/ 
{
   PARM* pThreadParm;
   // Initialize local pointer to void pointer passed to thread
   pThreadParm = (PARM*)vThreadParm;
   g_hConnect = 0;

   if ( !( g_hConnect = InternetConnect (
                            g_hOpen, 
                            pThreadParm->pHost,
                            INTERNET_INVALID_PORT_NUMBER,
                            pThreadParm->pUser,
                            pThreadParm->pPass,
                            INTERNET_SERVICE_FTP, 
                            0,
                            0 ) ) )
   {
       cerr << "Error on InternetConnnect: " << GetLastError() << endl;
       return 1; // failure
   }
   
   return 0;  // success
}

원본은 요기 ↓
http://support.microsoft.com/default.aspx?scid=kb;en-us;224318

posted by 뚱2