Aracılığıyla paylaş


Ortak İşlevler (Windows Internet)

Farklı İnternet protokolleri (ftp ve http gibi), internet üzerindeki bilgileri işlemek için aynı WinINet işlevlerinin birkaçını kullanır. Bu yaygın işlevler, uygulandıkları protokolden bağımsız olarak görevlerini tutarlı bir şekilde işler. Uygulamalar, farklı protokoller (ftp ve http için dosyaları okuma gibi) genelinde görevleri işleyen genel amaçlı işlevler oluşturmak için bu işlevleri kullanabilir.

Ortak işlevler aşağıdaki görevleri işler:

Ortak İşlevleri Kullanma

Aşağıdaki tabloda, WinINet işlevlerine dahil edilen yaygın işlevler listelenmektedir. Ortak işlevler farklı türde HINTERNET tanıtıcılarında veya farklı oturum türleri sırasında kullanılabilir.

Fonksiyon Açıklama
InternetFindNextFile Dosya numaralandırmaya veya aramaya devam eder. FtpFindFirstFileveya internetopenUrlişlevitarafından oluşturulmuş bir tanıtıcı gerektirir.
InternetLockRequestFile Kullanıcının kullanılan dosyaya kilit yerleştirmesine izin verir. Bu işlev, FtpOpenFile, HttpOpenRequestveya InternetOpenUrl işlevi tarafından döndürülen bir tanıtıcı gerektirir.
InternetQueryDataAvailable Kullanılabilir veri miktarını alır. FtpOpenFileveya httpOpenRequestişlevitarafından oluşturulmuş bir tanıtıcı gerektirir.
InternetQueryOption İnternet seçeneğinin ayarını alır.
internetreadfile URL verilerini okur. InternetOpenUrl, FtpOpenFileveya httpOpenRequestişlevitarafından oluşturulmuş bir tanıtıcı gerektirir.
InternetSetFilePointer Bir dosyadaki sonraki okumanın konumunu ayarlar. InternetOpenUrl (yalnızca HTTP URL'sinde) veya GET HTTP fiili kullanılarak HttpOpenRequest tarafından oluşturulan bir tanıtıcı gerektirir.
internetsetoption Bir İnternet seçeneği ayarlar.
internetsetstatuscallback Durum bilgilerini alan bir geri çağırma işlevi ayarlar. Belirlenen HINTERNET tanıtıcısına ve ondan türetilen tüm tanıtıcılara bir geri çağırma işlevi atar.
InternetUnlockRequestFile InternetLockRequestFile işlevi kullanılarak kilitlenen bir dosyanın kilidini açar.

 

Dosyaları okuma, sonraki dosyayı bulma, seçenekleri düzenleme ve zaman uyumsuz işlemleri ayarlama, çeşitli protokolleri destekleyen ve HINTERNET türleri işleyen işlevlerde ortaktır.

Dosyaları Okuma

InternetReadFile işlevi, InternetOpenUrl, FtpOpenFileveya HttpOpenRequest işlevi tarafından döndürülen BIR HINTERNET tanıtıcısından kaynak indirmek için kullanılır.

InternetReadFile, arabelleğin adresini içeren geçersiz bir işaretçi değişkenini ve arabelleğin uzunluğunu içeren bir değişkenin işaretçisini kabul eder. işlevi arabellekteki verileri ve arabelleğe indirilen veri miktarını döndürür.

WinINet işlevleri, kaynağın tamamını indirmek için iki teknik sağlar:

InternetQueryDataAvailable, InternetOpenUrl, FtpOpenFileveya HttpOpenRequest (tanıtıcıda httpSendRequestçağrıldıktansonra) tarafından oluşturulan HINTERNET tanıtıcısını alır ve kullanılabilir bayt sayısını döndürür. Uygulama kullanılabilir bayt sayısına eşit bir arabellek ve sonlandırıcı null karakteri için 1 arabellek ayırmalı ve bu arabelleği InternetReadFileile kullanmalıdır. InternetQueryDataAvailable asıl dosya değil üst bilgide listelenen dosya boyutunu denetlediğinden bu yöntem her zaman çalışmaz. Üst bilgi dosyasındaki bilgiler güncel olmayabilir veya üst bilgi dosyası şu anda tüm standartlarda gerekli olmadığından eksik olabilir.

Aşağıdaki örnek, hResource tanıtıcısı tarafından erişilen kaynağın içeriğini okur ve intCtrlID ile gösterilen düzenleme kutusunda görüntülenir.

int WINAPI Dumper(HWND hX, int intCtrlID, HINTERNET hResource)
{
    LPTSTR    lpszData;           // buffer for the data
    DWORD     dwSize;             // size of the data available
    DWORD     dwDownloaded;       // size of the downloaded data
    DWORD     dwSizeSum=0;        // size of the data in the text box
    LPTSTR    lpszHolding;        // buffer to merge the text box 
                                  // data and buffer

    // Set the cursor to an hourglass.
    SetCursor(LoadCursor(NULL,IDC_WAIT));

    // This loop handles reading the data.  
    do
    {
        // The call to InternetQueryDataAvailable determines the
        // amount of data available to download.
        if (!InternetQueryDataAvailable(hResource,&dwSize,0,0))
        {
            ErrorOut(hX,GetLastError(),TEXT("InternetReadFile"));
            SetCursor(LoadCursor(NULL,IDC_ARROW));
            return FALSE;
        }
        else
        {    
            // Allocate a buffer of the size returned by
            // InternetQueryDataAvailable.
            lpszData = new TCHAR[dwSize+1];

            // Read the data from the HINTERNET handle.
            if(!InternetReadFile(hResource,(LPVOID)lpszData,
                                 dwSize,&dwDownloaded))
            {
                ErrorOut(hX,GetLastError(),TEXT("InternetReadFile"));
                delete[] lpszData;
                break;
            }
            else
            {
                // Add a null terminator to the end of the 
                // data buffer.
                lpszData[dwDownloaded]='\0';

                // Allocate the holding buffer.
                lpszHolding = new TCHAR[dwSizeSum + dwDownloaded + 1];
                    
                // Check if there has been any data written to 
                // the text box.
                if (dwSizeSum != 0)
                {
                    // Retrieve the data stored in the text 
                    // box, if any.
                    GetDlgItemText(hX,intCtrlID,
                                   (LPTSTR)lpszHolding, 
                                   dwSizeSum);
                         
                    // Add a null terminator at the end of 
                    // the text box data.
                    lpszHolding[dwSizeSum]='\0';
                }
                else
                {
                    // Make the holding buffer an empty string. 
                    lpszHolding[0]='\0';
                }

                size_t cchDest = dwSizeSum + dwDownloaded + 
                                 dwDownloaded + 1;
                LPTSTR pszDestEnd;
                size_t cchRemaining;

                // Add the new data to the holding buffer.
                HRESULT hr = StringCchCatEx(lpszHolding, cchDest, 
                                            lpszData, &pszDestEnd, 
                                            &cchRemaining, 
                                            STRSAFE_NO_TRUNCATION);
                if(SUCCEEDED(hr))
                {
                    // Write the holding buffer to the text box.
                    SetDlgItemText(hX,intCtrlID,(LPTSTR)lpszHolding);

                    // Delete the two buffers.
                    delete[] lpszHolding;
                    delete[] lpszData;

                    // Add the size of the downloaded data to 
                    // the text box data size.
                    dwSizeSum = dwSizeSum + dwDownloaded + 1;

                    // Check the size of the remaining data.  
                    // If it is zero, break.
                    if (dwDownloaded == 0)
                    {
                        break;
                    }                    
                    else
                    {
                        //  Insert error handling code here.
                    }
                }
            }
        }
    }
    while(TRUE);

    // Close the HINTERNET handle.
    InternetCloseHandle(hResource);

    // Set the cursor back to an arrow.
    SetCursor(LoadCursor(NULL,IDC_ARROW));

    // Return.
    return TRUE;
}

InternetReadFile, okunan sıfır bayt döndürür ve kullanılabilir tüm veriler okunduğunda başarıyla tamamlar. Bu, bir uygulamanın InternetReadFile kullanarak verileri indirmesine ve okuması sıfır bayt döndürüp başarıyla tamamladığında çıkış yapmasına olanak tanır.

Aşağıdaki örnek, kaynağı İnternet'ten okur ve intCtrlID ile gösterilen düzenleme kutusunda görüntüler. HINTERNET tanıtıcısı hInternet, InternetOpenUrl, FtpOpenFileveya HttpOpenRequest tarafından döndürüldü (HttpSendRequesttarafından gönderildikten sonra).

int WINAPI Dump(HWND hX, int intCtrlID, HINTERNET hResource)
{
     DWORD dwSize = 0;
     LPTSTR lpszData;
     LPTSTR lpszOutPut;
     LPTSTR lpszHolding = TEXT("");
     int nCounter = 1;
     int nBufferSize = 0;
     DWORD BigSize = 8000;

     // Set the cursor to an hourglass.
     SetCursor(LoadCursor(NULL,IDC_WAIT));

     // Begin the loop that reads the data.
     do
     {
          // Allocate the buffer.
          lpszData =new TCHAR[BigSize+1];

          // Read the data.
          if(!InternetReadFile(hResource,
                              (LPVOID)lpszData,
                              BigSize,&dwSize))
          {
               ErrorOut(hX,GetLastError(),TEXT("InternetReadFile"));
               delete []lpszData;
               break;
          }
          else
          {
               // Add a null terminator to the end of the buffer.
               lpszData[dwSize]='\0';

               // Check if all of the data has been read.  This should
               // never get called on the first time through the loop.
               if (dwSize == 0)
               {
                    // Write the final data to the text box.
                    SetDlgItemText(hX,intCtrlID,lpszHolding);

                    // Delete the existing buffers.
                    delete [] lpszData;
                    delete [] lpszHolding;
                    break;
               }

               // Determine the buffer size to hold the new data and
               // the data already written to the text box (if any).
               nBufferSize = (nCounter*BigSize)+1;

               // Increment the number of buffers read.
               nCounter++;               

               // Allocate the output buffer.
               lpszOutPut = new TCHAR[nBufferSize];

               // Make sure the buffer is not the initial buffer.
               if(nBufferSize != int(BigSize+1))
               {
                    // Copy the data in the holding buffer.
                    StringCchCopy(lpszOutPut,nBufferSize,lpszHolding);
                    // Add error handling code here.

                    // Concatenate the new buffer with the 
                    // output buffer.
                    StringCchCat(lpszOutPut, nBufferSize, lpszData);
                    // Add error handling code here.
     
                    // Delete the holding buffer.
                    delete [] lpszHolding;
               }
               else
               {
                    // Copy the data buffer.
                    StringCchCopy(lpszOutPut, nBufferSize, lpszData);
                    // Add error handling code here.
               }

               // Allocate a holding buffer.
               lpszHolding = new TCHAR[nBufferSize]; 

               // Copy the output buffer into the holding buffer.
               memcpy(lpszHolding,lpszOutPut,nBufferSize);

               // Delete the other buffers.
               delete [] lpszData;
               delete [] lpszOutPut;

          }

     }
     while (TRUE);

     // Close the HINTERNET handle.
     InternetCloseHandle(hResource);

     // Set the cursor back to an arrow.
     SetCursor(LoadCursor(NULL,IDC_ARROW));

     // Return.
     return TRUE;
}

Sonraki Dosyayı Bulma

InternetFindNextFile işlevi, ftpFindFirstFileveya InternetOpenUrlarama parametreleri ve HINTERNET tanıtıcısı kullanılarak bir dosya aramasında sonraki dosyayı bulmak için kullanılır.

Dosya aramasını tamamlamak için, FtpFindFirstFiletarafından döndürülen HINTERNET tanıtıcısını kullanarak InternetFindNextFile çağırmaya devam edin veya ERROR_NO_MORE_FILESgenişletilmiş hata iletisiyle işlev başarısız olana kadar InternetOpenUrl. Genişletilmiş hata bilgilerini almak için GetLastError işlevini çağırın.

Aşağıdaki örnek, lstDirectory tarafından gösterilen liste kutusunda FTP dizininin içeriğini görüntüler. HINTERNET tanıtıcısı hConnect, bir FTP oturumu oluşturduktan sonra internetconnectişlevitarafından döndürülen bir tanıtıcıdır.

bool WINAPI DisplayDir( HWND hX, 
                        int lstDirectory, 
                        HINTERNET hConnect, 
                        DWORD dwFlag )
{
     WIN32_FIND_DATA pDirInfo;
     HINTERNET hDir;
     TCHAR DirList[MAX_PATH];

     // Set the cursor to an hourglass.
     SetCursor(LoadCursor(NULL,IDC_WAIT));

     // Reset the list box.
     SendDlgItemMessage(hX, lstDirectory,LB_RESETCONTENT,0,0);

     // Find the first file.
     hDir = FtpFindFirstFile (hConnect, TEXT ("*.*"), 
                              &pDirInfo, dwFlag, 0);
     if (!hDir)                                     
     {
          // Check if the error was because there were no files.
          if (GetLastError()  == ERROR_NO_MORE_FILES) 
          {
               // Alert user.
               MessageBox(hX, TEXT("There are no files here!!!"), 
                          TEXT("Display Dir"), MB_OK);

               // Close the HINTERNET handle.
               InternetCloseHandle(hDir);

               // Set the cursor back to an arrow.
               SetCursor(LoadCursor(NULL,IDC_ARROW));

               // Return.
               return TRUE;
          }
          else 
          {
               // Call error handler.
               ErrorOut (hX, GetLastError (), TEXT("FindFirst error: "));

               // Close the HINTERNET handle.
               InternetCloseHandle(hDir);

               // Set the cursor back to an arrow.
               SetCursor(LoadCursor(NULL,IDC_ARROW));

               // Return.
               return FALSE;
          }
     }
     else
     {
          // Write the file name to a string.
          StringCchPrintf(DirList, MAX_PATH, pDirInfo.cFileName);

          // Check the type of file.
          if (pDirInfo.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
          {
               // Add <DIR> to indicate that this is 
               // a directory to the user.
               StringCchCat(DirList, MAX_PATH, TEXT(" <DIR> "));
               // Add error handling code here.
          }
       
          // Add the file name (or directory) to the list box.
          SendDlgItemMessage(hX, lstDirectory, LB_ADDSTRING,
                             0, (LPARAM)DirList);
     }
     do
     {
          // Find the next file.
          if (!InternetFindNextFile (hDir, &pDirInfo))
          {
               // Check if there are no more files left. 
               if ( GetLastError() == ERROR_NO_MORE_FILES ) 
               {
                    // Close the HINTERNET handle.
                    InternetCloseHandle(hDir);

                    // Set the cursor back to an arrow.
                    SetCursor(LoadCursor(NULL,IDC_ARROW));

                    // Return.
                    return TRUE;
               }
               else
               {   
                    // Handle the error.
                    ErrorOut (hX, GetLastError(), 
                              TEXT("InternetFindNextFile"));

                    // Close the HINTERNET handle.
                    InternetCloseHandle(hDir);

                    // Set the cursor back to an arrow.
                    SetCursor(LoadCursor(NULL,IDC_ARROW));

                    // Return.
                    return FALSE;
               }
           }
           else
           {
               // Write the file name to a string.
               StringCchPrintf(DirList, MAX_PATH, pDirInfo.cFileName);

               // Check the type of file.
               if(pDirInfo.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY)
               {
                    // Add <DIR> to indicate that this is a 
                    // directory to the user.
                    StringCchCat(DirList, MAX_PATH, TEXT(" <DIR> "));
                    // Add error handling code here.
               }
     
               // Add the file name (or directory) to the list box.
               SendDlgItemMessage(hX, lstDirectory, LB_ADDSTRING,
                                  0, (LPARAM)DirList);
           }
     }
     while ( TRUE);
     
}

Seçenekleri Düzenleme

InternetSetOption ve InternetQueryOption, WinINet seçeneklerini işlemek için kullanılır.

InternetSetOption ayar seçeneğini belirten bir değişken, seçenek ayarını tutacak bir arabellek ve arabellecin uzunluğunu içeren değişkenin adresini içeren bir işaretçi kabul eder.

InternetQueryOption alma seçeneğini belirten bir değişken, seçenek ayarını tutacak bir arabellek ve arabellecin uzunluğunu içeren değişkenin adresini içeren bir işaretçiyi kabul eder.

Zaman Uyumsuz İşlemleri Ayarlama

Varsayılan olarak, WinINet işlevleri zaman uyumlu olarak çalışır. Bir uygulama, InternetOpen işlevine yapılan çağrıda INTERNET_FLAG_ASYNC bayrağını ayarlayarak zaman uyumsuz işlem isteyebilir. gelecekte InternetOpen döndürülen tanıtıcıdan türetilen tanıtıcılara karşı yapılan tüm çağrılar zaman uyumsuz olarak yapılır.

Zaman uyumsuz ve zaman uyumlu işlemin mantığı, tek iş parçacıklı bir uygulamanın ağ G/Ç'sinin tamamlanmasını beklemek zorunda kalmadan CPU kullanımını en üst düzeye çıkarmasına izin vermektir. Bu nedenle, isteğe bağlı olarak işlem zaman uyumlu veya zaman uyumsuz olarak tamamlanabilir. Uygulamanın dönüş kodunu denetlemesi gerekir. bir işlev FALSE veya NULLdöndürürse ve GetLastErrorERROR_IO_PENDING döndürürse, istek zaman uyumsuz olarak yapılır ve işlev tamamlandığında uygulama INTERNET_STATUS_REQUEST_COMPLETE ile geri çağrılır.

Zaman uyumsuz işleme başlamak için uygulamanın çağrısında INTERNET_FLAG_ASYNC bayrağını InternetOpenolarak ayarlaması gerekir. Uygulamanın daha sonra internetsetstatuscallbackkullanarak geçerli bir geri çağırma işlevi kaydetmesi gerekir.

Bir tanıtıcı için geri çağırma işlevi kaydedildikten sonra, tanıtıcı oluşturulduğunda sağlanan bağlam değerinin sıfır olmaması koşuluyla bu tanıtıcı üzerindeki tüm işlemler durum göstergeleri oluşturabilir. Sıfır bağlam değeri sağlamak, InternetOpeniçinde INTERNET_FLAG_ASYNC belirtilmesine rağmen bir işlemin zaman uyumlu bir şekilde tamamlanmasını zorlar.

Durum göstergeleri, uygulamaya ana bilgisayar adını çözümleme, sunucuya bağlanma ve veri alma gibi ağ işlemlerinin ilerleme durumu hakkında geri bildirim sağlar. Bir tanıtıcı için üç özel amaçlı durum göstergesi yapılabilir:

  • INTERNET_STATUS_HANDLE_CLOSING, tanıtıcı için yapılan son durum göstergesidir.
  • INTERNET_STATUS_HANDLE_CREATED tanıtıcının ilk ne zaman oluşturulduğunu gösterir.
  • INTERNET_STATUS_REQUEST_COMPLETE, zaman uyumsuz bir işlemin tamamlandığını gösterir.

Uygulamanın, INTERNET_STATUS_REQUEST_COMPLETE bir gösterge aldıktan sonra işlemin başarılı mı yoksa başarısız mı olduğunu belirlemek için INTERNET_ASYNC_RESULT yapısını denetlemesi gerekir.

Aşağıdaki örnekte bir geri çağırma işlevi örneği ve işlevi geri çağırma işlevi olarak kaydetmek için InternetSetStatusCallbackçağrısı gösterilmektedir.

void CALLBACK InternetCallback(
    HINTERNET hInternet,
    DWORD_PTR dwcontext,
    DWORD dwInternetStatus,
    LPVOID lpvStatusInformation,
    DWORD dwStatusInformationLength
    )
{
    _tprintf(TEXT("%0xd %0xp %0xd %0xp %0xd\n"),
             hInternet,
             dwcontext,
             dwInternetStatus,
             lpvStatusInformation,
             dwStatusInformationLength);
};

INTERNET_STATUS_CALLBACK dwISC =
    InternetSetStatusCallback(hInternet, InternetCallback); 

HINTERNET Tanıtıcılarını Kapatma

tüm HINTERNET tanıtıcıları InternetCloseHandle işlevi kullanılarak kapatılabilir. İstemci uygulamaları, HINTERNET tanıtıcısından türetilen tüm HINTERNET tanıtıcılarını, tanıtıcıda InternetCloseHandle çağırmadan önce kapatmaya çalıştıkları tanıtıcıları kapatmalıdır.

Aşağıdaki örnekte tanıtıcı hiyerarşisi gösterilmektedir.

HINTERNET hRootHandle, hOpenUrlHandle;

hRootHandle = InternetOpen( TEXT("Example"), 
                            INTERNET_OPEN_TYPE_DIRECT, 
                            NULL, 
                            NULL, 0);

hOpenUrlHandle = InternetOpenUrl(hRootHandle, 
    TEXT("https://www.server.com/default.htm"), NULL, 0, 
    INTERNET_FLAG_RAW_DATA,0);

// Close the handle created by InternetOpenUrl so that the
// InternetOpen handle can be closed.
InternetCloseHandle(hOpenUrlHandle); 

// Close the handle created by InternetOpen.
InternetCloseHandle(hRootHandle);

Kaynakları Kilitleme ve Kilidini Açma

InternetLockRequestFile işlevi, uygulamanın HINTERNET tanıtıcısıyla ilişkili önbelleğe alınmış kaynağın önbellekten kaybolmadığından emin olmasını sağlar. Başka bir indirme, kilitli dosyayla aynı URL'ye sahip bir kaynağı işlemeye çalışırsa, önbellek güvenli bir silme işlemi yaparak dosyanın kaldırılmasını önler. Uygulama InternetUnlockRequestFile işlevini çağırdıktan sonra önbelleğe dosyayı silme izni verilir.

INTERNET_FLAG_NO_CACHE_WRITE veya INTERNET_FLAG_DONT_CACHE bayrağı ayarlanmışsa InternetLockRequestFile, tanıtıcı bir https kaynağına bağlı olmadığı sürece TMP uzantısıyla geçici bir dosya oluşturur. İşlev bir https kaynağına erişiyorsa ve INTERNET_FLAG_NO_CACHE_WRITE (veya INTERNET_FLAG_DONT_CACHE) ayarlanmışsa, InternetLockRequestFilebaşarısız olur.

Not

WinINet, sunucu uygulamalarını desteklemez. Ayrıca, bir hizmetten kullanılmamalıdır. Sunucu uygulamaları veya hizmetleri için Microsoft Windows HTTP Services (WinHTTP)kullanın.