Help and Support
 

powered byLive Search

How To Control Connection Timeout Value by Creating Second Thread

Retired KB ArticleThis article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.
Article ID:224318
Last Review:June 29, 2004
Revision:2.2
This article was previously published under Q224318

SUMMARY

This acticle shows a workaround to the InternetSetOption API bug on setting timeout values by creating a second thread.
InternetSetOption Does Not Set Timeout Values

MORE INFORMATION

The following sample code controls how long to wait while connecting to the FTP server in WinInet. It creates a worker thread to call the blocking WinInet APIs. If the connection takes more time than the specified timeout value, the original thread will call InternetCloseHandle to release the blocking WinInet function. For HTTP communications the same idea applies. In the case of HTTP, the actual connection occurs in the call to HttpSendRequest.
   #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
   }
				

APPLIES TO
Microsoft Internet Explorer 4.0 128-Bit Edition
Microsoft Internet Explorer 4.01 Service Pack 2
Microsoft Internet Explorer 4.01 Service Pack 1
Microsoft Internet Explorer 5.0
Microsoft Internet Explorer 5.5

Back to the top

Keywords: 
kbftp kbhowto kbhttp KB224318

Article Translations

 

Other Support Options

  • Need More Help?
    Contact a Support professional by Email, Online or Phone.
  • Customer Service
    For non-technical assistance with product purchases, subscriptions, online services, events, training courses, corporate sales, piracy issues, and more.
  • Newsgroups
    Pose a question to other users. Discussion groups and Forums about specific Microsoft products, technologies, and services.