日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

WinInet库之Http通信

發布時間:2023/12/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WinInet库之Http通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
// 超文本傳輸協議(HyperText Transfer Protocol)是互聯網上應用最廣泛的協議,主要是用于網頁的瀏覽。 // HTTP采用了請求-應答模式,也就是俗稱的客戶端/服務器模型,簡稱C/S模型。 // 其中,客戶端向服務器發送一個請求,請求一般包括請求行、請求頭和請求體三個部分。 // 在請求頭中包含請求頭中包含請求方法、URL、協議版本以及請求修飾符,客戶消息和內容的類似于MIME的消息結構。 // 服務器以一個狀態作為響應,響應的內容包括消息協議的版本,成功或者錯誤編碼加上包含服務器信息、實體元信息以及可能的實體內容。// HTTP常用的請求方法有GET、POST、PUT、DELETE四個,對應著對網絡資源的查、改、增、刪四個操作。 // HTTP采用TCP通信,主要是保證傳輸數據的穩定性、完整性。// HTTP文件上傳,主要是向服務器發送POST請求,將數據按照服務器的接收格式傳輸到服務器上,服務器再根據接收格式接收數據,完成文件的上傳操作。 // HTTP文件下載,主要是向服務器發送GET請求,服務器接收到相應的請求后,便會讀取資源數據并返回,這就完成的文件下載操作。// PS:HttpOpenRequest函數: // 功能:創建一個HTTP請求句柄。 // 原型:HINTERNET HttpOpenRequest( // _In_ HINTERNET hConnect, // _In_ LPCTSTR lpszVerb, // _In_ LPCTSTR lpszObjectName, // _In_ LPCTSTR lpszVersion, // _In_ LPCTSTR lpszReferer, // _In_ LPCTSTR *lplpszAcceptTypes, // _In_ DWORD dwFlags, // _In_ DWORD_PTR dwContext // ) // 參數:hConnect:由InternetConnect函數返回的連接句柄。 // lpszVerb:請求的方法,默認為GET。 // lpszObjectName:目標對象字符串,通常為文件名稱、可自行模塊或者查找標識符。 // lpszVersion:HTTP版本,如果為NULL,表示使用1.1或1.0版本的HTTP協議。 // lpszReferer:指向URL文檔地址,如果為NULL,則不指定HTTP頭。 // lplpszAcceptTypes:表示客戶接受的內容類型,比如"text/json"等。 // dwFlags:標志,可以為以下值的一個或多個: // INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP:禁用檢測這種特殊類型的重定向。 // INTERNET_FLAG_IGNORE_CERT_CN_INVALID:根據請求中給出的主機名禁用檢測從服務器返回的基于SSL/PCT的證書。 // INTERNET_FLAG_KEEP_CONNECTION:保持連接。 // INTERNET_FLAG_NO_AUTH:不會自動嘗試驗證。 // INTERNET_FLAG_NO_COOKIES:不會自動為請求添加Cookie標頭,也不會自動將返回的Cookie添加到Cookie數據庫。 // INTERNET_FLAG_NO_UI:禁用Cookie對話框。 // INTERNET_FLAG_RELOAD:強制從源服務器上下載所請求的文件,而不是從緩存中下載。 // INTERNET_FLAG_SECURE:啟用HTTPS。 // dwContext:指定OpenRequest操作的上下文標識。 // 結果:成功返回HTTP請求句柄,失敗返回NULL。// PS:HttpSendRequestEx函數: // 功能:將指定的請求發送到HTTP服務器。 // 原型:BOOL HttpSendRequestEx( // _In_ HINTERNET hRequest, // _In_ LPINTERNET_BUFFERS lpBuffersIn, // _Out_ LPINTERNET_BUFFERS lpBuffersOut, // _In_ DWORD dwFlags, // _In_ DWORD_PTR dwContext // ) // 參數:hRequest:由HttpOpenRequest創建的請求句柄。 // lpBuufersIn:可選,指向INTERNET_BUFFERS結構的指針。 // lpBuffersOut:保留,必須為NULL。 // dwFlags:保留,必須為NULL。 // dwContext:指定由應用程序定義的上下文值,前提是狀態回調函數已注冊。 // 結果:成功返回TRUE,失敗返回FALSE。// PS:HttpQueryInfo函數: // 功能:查詢有關HTTP請求的信息。 // 原型:BOOL WINAPI HttpQueryInfo( // HINTERNET hRequest, // DWORD dwInfoLevel, // LPVOID lpBuffer, // LPDWORD lpdwBufferLength, // LPDWORD lpdwIndex // ) // 參數:hRequest:由HttpOpenRequest函數創建的Request句柄。 // dwInfoLevel:請求要查詢的屬性和修改請求的標志組合。 // lpBuffer:接收信息的緩存區。 // lpdwBufferLength:接收緩存區大小。 // lpdwIndex:用于枚舉具有相同名稱的多個頭的基于零的頭索引。 // 結果:成功,返回TURE,失敗,返回FALSE。// PS:基于WinInet庫實現的HTTP文件上傳步驟如下: // 1.調用InternetCrackUrl函數對Url進行分解,從URL中提取網站的域名、資源路徑、用戶名、密碼以及URL的附加信息等。 // 2.調用InternetOpen函數建立會話,獲取會話句柄。連接過程中要指明INTERNET_SERVICE_HTTP,這表明連接到HTTP服務器上。 // 3.調用InternetConnect函數建立連接,獲取連接句柄。 // 4.調用HttpOpenRequest打開HTTP的POST請求,同時指明POST的資源路徑,并且設置HTTP的訪問標志。 // 5.調用HttpSendRequestEx函數向服務器發送訪問請求。 // 6.調用InternetWriteFile函數將本地數據寫到遠程主機上,即向服務器上傳數據。等數據上傳完畢后,調用HttpEndRequest函數來結束請求。 // 7.關閉句柄,釋放緩存區資源。// PS:示例代碼:// 數據上傳 BOOL Http_Upload(char *pszUploadUrl, BYTE *pUploadData, DWORD dwUploadDataSize) {// 變量(略)// 分解URLif (FALSE == Http_UrlCrack(pszUploadUrl, szScheme, szHostName, szUserName, szPassword, szUrlPath, szExtraInfo, MAX_PATH)){return FALSE;}// 數據上傳do {// 建立會話hInternet = ::InternetOpen("WinInet Http Upload v1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);if (NULL == hInternet){Http_ShowError("InternetOpen");break;}// 建立連接hConnect = ::InternetConnect(hInternet, szHostName, INTERNET_DEFAULT_HTTP_PORT, szUserName, szPassword, INTERNET_SERVICE_HTTP, 0, 0);if (NULL == hConnect){Http_ShowError("InternetConnect");break;}// 拼接szUrlPathif (0 < ::lstrlen(szExtraInfo)){::lstrcat(szUrlPath, szExtraInfo);}// 設置標記dwOpenRequestFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP | INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_COOKIES |INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD;// 創建POST請求hRequest = ::HttpOpenRequest(hConnect, "POST", szUrlPath, NULL, NULL, NULL, dwOpenRequestFlags, 0);if (NULL == hRequest){Http_ShowError("HttpOpenRequest");break;}// 發送請求,告訴服務器傳輸數據的總大小::RtlZeroMemory(&internetBuffers, sizeof(internetBuffers));internetBuffers.dwStructSize = sizeof(internetBuffers);internetBuffers.dwBufferTotal = dwPostDataSize;bRet = ::HttpSendRequestEx(hRequest, internetBuffers, NULL, 0, 0);if (FALSE == bRet){break;}// 發送數據bRet = ::InternetWriteFile(hRequest, pUploadData, dwUploadDataSize, &dwRet);if (FALSE == bRet){break;}// 發送完畢,結束請求bRet = ::HttpEndRequest(hRequest, NULL, 0, 0);if (FALSE == bRet){break;}// 接收響應報文信息頭pResponseHeaderInfo = new unsigned char[dwResponseHeaderInfoSize];if (NULL == pResponseHeaderInfo){break;}::RtlZeroMemory(pResponseHeaderInfo, dwResponseHeaderInfoSize);bRet = ::HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, pResponseHeaderInfo, &dwResponseHeaderInfoSize, NULL);if (FALSE == bRet){Http_ShowError("HttpQueryInfo");break;}// 從字段"Content-Length"中獲取數據長度bRet = Http_GetContentLength((char*)pResponseHeaderInfo, &dwResponseHeaderInfoSize);if (FALSE == bRet){break;}// 接收報文主體內容pBuf = new BYTE[dwBufSize];if (NULL = pBuf){break;}pResponseBodyData = new BYTE[dwResponseBodyDataSize];if (NULL == pResponseBodyData){break;}::RtlZeroMemory(pResponseBodyData, dwResponseBodyDataSize);do{::RtlZeroMemory(pBuf, dwBufSize);bRet = ::InternetReadFile(hRequest, pBuf, dwBufSize, &dwRet);if (FALSE == bRet){Http_ShowError("InternetReadFile");break;}::RtlCopyMemory((pResponseBodyData + dwOffset), pBuf, dwRet);dwOffset += dwRet;} while (dwResponseBodyDataSize > dwOffset);} while (FALSE);// 關閉并釋放(略)return bRet; }// PS:基于WinInet庫的HTTP文件下載步驟: // 1.調用InternetCrackUrl函數分解URL,從URL中提取網站的域名、資源路徑以及URL的附加信息等。 // 2.調用InternetOpen函數建立會話并獲取會話句柄。 // 3.調用InternetConnect函數建立連接,并指定連接的類型為INTERNET_SERVICE_HTTP,即連接到HTTP服務器上。 // 4.使用HttpOpenRequest創建一個GET請求,同時指明訪問服務器的資源路徑并設置HTTP的訪問標志。 // 5.使用HttpSendRequestEx函數將訪問請求發送到服務器上。這樣服務器就可以獲取請求信息和返回響應頭信息。 // 6.調用HttpQueryInfo函數獲取返回的Response Header信息,并根據Content-Length字段中的數據確定接收的數據長度,申請接收數據的緩存區。 // 7.循環調用InternetReadFile函數接收數據,直到接收數據的長度等于返回數據的長度。 // 8.關閉句柄,釋放數據緩存區。// PS:示例代碼:// 數據下載BOOL Http_Download(char* pszDownloadUrl, BYTE **ppDownloadData, DWORD *pdwDownloadDataSize) {// 變量(略)// 分解URLif (FALSE == Http_UrlCrack(pszDownloadUrl, szScheme, szHostName, szUserName, szPassword, szUrlPath, szExtraInfo, MAX_PATH)){return FALSE;}// 拼接szUrlPathif (0 < ::lstrlen(szExtraInfo)){::lstrcat(szUrlPath, szExtraInfo);}// 數據下載do {// 建立會話hInternet = ::InternetOpen("WinInte Http Download v1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);if (NULL == hInternet){Http_ShowError("InternetOpen");break;}// 建立連接hConnect = ::InternetConnect(hInternet, szHostName, INTERNET_DEFAULT_HTTP_PORT, szUserName, szPassword, INTERNET_SERVICE_HTTP, 0, 0);if (NULL == hConnect){Http_ShowError("InternetConnect");break;}// 設置標志dwOpenRequestFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP | INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_COOKIES |INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD;// 創建請求hRequest = ::HttpOpenRequest(hConnect, "GET", szUrlPath, NULL, NULL, NULL, dwOpenRequestFlags, 0);if (NULL == hRequest){Http_ShowError("HttpOpenRequest");break;}// 發送請求bRet = ::HttpSendRequestEx(hRequest, NULL, 0, NULL, 0);if (FALSE == bRet){Http_ShowError("HttpSendRequestEx");break;}// 接收響應的報文信息頭pResponseHeaderInfo = new unsigned char[dwResponseHeaderInfoSize];if (NULL == pResponseHeaderInfo){break;}::RtlZeroMemory(pResponseHeaderInfo, dwResponseHeaderInfoSize);// 查詢響應信息頭bRet = ::HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, pResponseHeaderInfo, &dwResponseHeaderInfoSize);if (FALSE == bRet){Http_ShowError("HttpQueryInfo");break;}// 從字段"Content-Length"中獲取數據長度bRet = Http_GetContentLength((char*)pResponseHeaderInfo, dwResponseHeaderInfoSize);if (FALSE == bRet){break;}// 申請動態內存,用于接收報文主體數據pBuf = new BYTE[dwBufSize];if (NULL == pBuf){break;}::RtlZeroMemory(pDownloadData, dwDownloadDataSize);// 循環接收數據do {::RtlZeroMemory(pBuf, dwBufSize);bRet = ::InternetReadFile(hRequest, pBuf, dwBufSize, &dwRet);if (FALSE == bRet){break;}::RtlCopyMemory((PVOID)(pDownloadData + dwOffset), pBuf, dwRet);dwOffset += dwRet;} while (dwDownloadDataSize > dwOffset);// 返回數據**ppDownloadData = pDownloadData;*pdwDownloadDataSize = dwDownloadDataSize;} while (FALSE);// 關閉句柄,釋放緩存區(略)return bRet; }

總結

以上是生活随笔為你收集整理的WinInet库之Http通信的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。