<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

           HTTP是很常見的協議,雖然用得很多,但對細節的了解卻是很淺,這回通過向服務端上傳文件信息來理解細節。網絡庫的選擇:1、WinHTTP是windows下常用的庫;2、CURL是廣受喜愛的開源庫。對于我來說,libcurl最大的優點是使用方便,可以把注意力更多的集中到業務層上,提高工作效率,避免重造輪子;缺點是略大(MD編譯有264KB,MT編譯有340KB),不像WinHTTP可以由windows操作系統集成。下邊展示如何使用這兩種網絡庫實現表單POST文件。

      一、libcurl

           庫編譯:把include、lib的代碼拿出來,使用靜態庫,設置預定義宏BUILDING_LIBCURL。
           測試工程:設置預定義宏CURL_STATICLIB;添加依賴lib:Ws2_32.lib Wldap32.lib。
           主要代碼
      void curl_post_cswuyg()
      {
          curl_global_init(CURL_GLOBAL_ALL);
          CURL* hCurl = curl_easy_init();
          if(hCurl != NULL)
          {
              //也許有Expect: 100-continue,去掉它
              curl_slist* pOptionList = NULL;
              pOptionList = curl_slist_append(pOptionList, "Expect:");
              curl_easy_setopt(hCurl, CURLOPT_HTTPHEADER, pOptionList);
      
              curl_httppost* pFormPost = NULL;
              curl_httppost* pLastElem = NULL;
              //上傳文件,指定本地文件完整路徑
              curl_formadd(&pFormPost, &pLastElem, CURLFORM_COPYNAME, "ufile01", CURLFORM_FILE, "C:\\temp\\upload_test_curl_cswuyg.txt", CURLFORM_CONTENTTYPE, "application/octet-stream", CURLFORM_END);
      
              //上傳自定義文件內容的文件,CURLFORM_BUFFER指定服務端文件名
              //http://curl.haxx.se/libcurl/c/curl_formadd.html
              char* file_info = "file_info——cswuyg";
              int record_length = std::string(file_info).length();
              curl_formadd(&pFormPost, &pLastElem,
                  CURLFORM_COPYNAME, "ufile01",
                  CURLFORM_BUFFER, "cswuyg_test.txt",
                  CURLFORM_BUFFERPTR, file_info,
                  CURLFORM_BUFFERLENGTH, record_length,
                  CURLFORM_END);
              //不加一個結束的hfs服務端無法寫入文件,一般不存在這種問題,這里加入只是為了測試.
              //curl_formadd(&pFormPost, &pLastElem, CURLFORM_COPYNAME, "end", CURLFORM_COPYCONTENTS, "end", CURLFORM_END);
              curl_easy_setopt(hCurl, CURLOPT_HTTPPOST, pFormPost);
              curl_easy_setopt(hCurl, CURLOPT_URL, "http://127.0.0.1/hfs_up/");
      
              CURLcode res = curl_easy_perform(hCurl);
              if(res != CURLE_OK)
              {
                  std::wcout << "Error" << std::endl;
              }
              curl_formfree(pFormPost);
              curl_easy_cleanup(hCurl);
          }
      
          curl_global_cleanup();
      }
           wireshark抓包,127.0.0.1地址無法抓到,網絡上有解決方案。示意圖:
      頭域設置分割符:
       MIME部分:
       

      二、WinHTTP

           庫:winhttp.lib
           主要代碼
      void cswuyg_winhttp_post()
      {
          HINTERNET hSession = ::WinHttpOpen(L"cswuyg post test/1.0", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, NULL);
          HINTERNET hConnect = ::WinHttpConnect(hSession, L"127.0.0.1", INTERNET_DEFAULT_HTTP_PORT, 0);
          if (hConnect == NULL)
          {
              int i = ERROR_WINHTTP_INCORRECT_HANDLE_TYPE;
              return;
          }
          const wchar_t* lpszAcceptedType[] = {L"*/*", NULL};
          HINTERNET hRequest = ::WinHttpOpenRequest(hConnect, L"POST", L"hfs_up", L"HTTP/1.1", WINHTTP_NO_REFERER, lpszAcceptedType, 0);
          if (hRequest == NULL)
          {
              return;
          }
          DWORD dwTime = 5000;
          ::WinHttpSetOption(hRequest, WINHTTP_OPTION_CONNECT_TIMEOUT, &dwTime, sizeof(DWORD));
          std::wstring strHeader = L"Content-Type: multipart/form-data; boundary=--boundary_cswuygtest\r\n";
          ::WinHttpAddRequestHeaders(hRequest, strHeader.c_str(), strHeader.length(), WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
      
          std::string strMIME = "----boundary_cswuygtest\r\n";
          strMIME += "Content-Disposition: form-data; name=\"ufile01\"; filename=\"upload_test_http_cswuyg.txt\"\r\n";
          strMIME += "Content-Type:application/octet-stream\r\n\r\n";
          strMIME += "1\r\n";
          /////////////////////////////
          //除了這個表單之外,后頭還必須要有另外的表單信息,否則hfs服務端那邊無法寫入文件,這里僅為測試。
          //strMIME += "----boundary_cswuygtest\r\n" ;
          //strMIME += "Content-Disposition: form-data; name=\"name\"\r\n\r\n";
          //strMIME += "temp.txt\r\n";
          /////////////////////////
          strMIME += "----boundary_cswuygtest--\r\n";
          /////////////////////////
          //可以直接寫入
          //::WinHttpSendRequest(hRequest, strHeader.c_str(), strHeader.length(), (LPVOID)strMIME.c_str(), strMIME.length(), strMIME.length(), 0);
      
          //也可以后面分步寫入
          ::WinHttpSendRequest(hRequest, NULL, 0, NULL, 0, strMIME.length(), 0);
          DWORD dwWritten = 0;
          while(!strMIME.empty())
          {
              ::WinHttpWriteData(hRequest, strMIME.c_str(), strMIME.length(), &dwWritten);
              if (strMIME.length() > dwWritten)
              {
                  strMIME.substr(dwWritten);
              }
              else
              {
                  strMIME = "";
              }
              
          }
          ::WinHttpReceiveResponse(hRequest, NULL);
      
          char buf[1024] = { 0 };
          DWORD dwToRead = 1024;
          DWORD dwHaveRead = 0;
          ::WinHttpReadData(hRequest, buf, dwToRead, &dwHaveRead);
          std::cout << buf << std::endl;
          ::WinHttpCloseHandle(hRequest);
          ::WinHttpCloseHandle(hConnect);
          ::WinHttpCloseHandle(hSession);
      }
           wireshark抓包
      頭域設置:
        表單設置:
       

      三、總結

           這兩個例子用hfs做服務器測試可以發現在上傳文件夾中上傳了文件,代碼都很簡單。測試過程中的最重要的是能盡快的反饋結果,所以能自己搭建一個http服務器很重要,hfs工具,非常簡單便捷。
        POST表單最重要的是了解表單的格式。首先要在頭域增加Content-Type說明,如:“content-type:multipart/from-data; boundary=--cswuyg”。然后http body填充的數據要以MIME格式上傳,每部分數據的開頭都是由“--”+boundary開始的,結尾以"--"+boundary+"--"結束。
        如果要上傳文件,需要跟服務器約定好格式,譬如上邊例子約定在content-Disposition中有filename鍵的則是上傳文件信息,該片的content為文件數據,這應該是比較通用的約定。
       
      附上部分資料

      MIME:http://baike.baidu.com/view/160611.htm
      MIME來源 : Multipurpose Internet Mail Extensions 多用途互聯網郵件擴展。服務器會將它們發送的多媒體數據的類型告訴瀏覽器,而通知手段就是說明該多媒體數據的MIME類型。
      GZIP文件:application/x-gzip
      任意的二進制數據:application/octet-stream.
      普通文本:text/plain

      wireshark:
      MIME Multipart Media Encapsulation 代表使用表單上傳的所有數據
      Encapsulated multipart part 代表表單中不同項的數據
      Boundary 用來隔開表單中不同部分的數據
      每部分數據的開頭都是由“--”+boundary開始的。
      如果使用wireshark抓包,而http使用的不是默認的80端口,那么需要抓TCP包,然后再強制Decode為http。
       
      HTTP協議的文檔:
       
      chroimumde breakpad_sender代碼中也有post表單上傳文件部分,只不過它是用WinInet寫的。
       
      2015 補充上傳文件時的抓包信息:
      posted on 2013-07-11 22:43  -銀光-  閱讀(108847)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 亚洲无码a∨在线视频| 亚洲精品一品二品av| 国产午夜福利小视频合集| 免费观看添你到高潮视频| 欧美刺激性大交| 九九热在线视频只有精品| 中文无码av一区二区三区| 99在线小视频| 国产农村老熟女国产老熟女| 亚洲精品97久久中文字幕无码| 日本中文字幕有码在线视频| 一本无码在线观看| 国产成人亚洲综合| 亚洲av无码成人精品区一区| 一亚洲一区二区中文字幕| 无码人妻一区二区三区兔费| 涿鹿县| 夜夜添无码一区二区三区| 日韩在线视频线观看一区| 久久久久久曰本av免费免费| 日韩免费无码视频一区二区三区| 久久国产精品伊人青青草| 55夜色66夜色国产精品视频| 精品一区二区三区蜜桃久| 无码人妻斩一区二区三区| 特级av毛片免费观看| 欧美做受视频播放| 五月丁香啪啪| 国产又色又爽又刺激在线观看| 久久国内精品一区二区三区| 少妇xxxxx性开放| 狼色精品人妻在线视频| 日韩精品无码去免费专区 | 亚洲高清aⅴ日本欧美视频| 人妻综合专区第一页| 国产成人精品亚洲资源| 精品人妻少妇一区二区三区| 99精品久久久中文字幕| 国内精品久久人妻无码不卡| 亚洲av激情五月性综合| 99久久亚洲综合精品成人|