使用WinHTTP与服务器通讯

目录

使用WinHTTP与服务器通讯

https://img-blog.csdn.net/20161202212238295

在与服务器交互之前, 必须用调用WinHttpOpen进行初始化,WinHttpOpen创建一个会话,并返回该会话的句柄,接着有了这个句柄, WinHttpConnect就能指定一个目标服务器

注意:调用了WinHttpConnect并不意味着和服务器建立了真正的连接

 WinHttpOpenRequest函数打开一个HTTP请求并返回一个HINTERNET 句柄,该句柄在接下来的步骤中会用到
 , WinHttpOpenRequest并不会向服务器发送请求, 实际上是WinHttpSendRequest通过网络与服务器建立连接并发送请求.

WinHttpSendRequest工作时需要 第二步中WinHttpOpenRequest返回的HINTERNET 句柄,WinHttpSendRequest可以发送额外的头部和其他信息,这个"其他信息"通常在PUT和POST操作中被使用

为了能够向使用POST或者PUT方法,在调用WinHttpOpenRequest时,第五个参数必须设置为"PUT"或者"POST",注意要使用大写,WinHttpSendRequest的第几个参数要设置为准备传送的数据的字节数, 然后就可以使用WinHttpWriteData来传送数据了

如果不想用 WinHttpWriteData 传送数据,则需要把 WinHttpSendRequest 第五个和第六个参数设置都为准备传送的数据的字节数,第四个参数为待传送数据的地址。

这样就可以直接在WinHttpSendRequest 中传送数据了在用 WinHttpOpenRequest 打开了一个请求,用 WinHttpSendRequest 发送数据并用 WinHttpReceiveResponse 接受返回消息之后,就能够用 WinHttpReadData 和 WinHttpQueryDataAvailable从HTTP 服务器下载资源了

DWORD dwSize = 0;
  DWORD dwDownloaded = 0;
  LPSTR pszOutBuffer;
  BOOL  bResults = FALSE;
  HINTERNET  hSession = NULL, 
             hConnect = NULL,
             hRequest = NULL;

  // 获得一个会话的句柄.
  hSession = WinHttpOpen( L"WinHTTP Example/1.0",  
                          WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                          WINHTTP_NO_PROXY_NAME, 
                          WINHTTP_NO_PROXY_BYPASS, 0 );

  // 指定HTTP服务器.
  if( hSession )
    hConnect = WinHttpConnect( hSession, L"www.microsoft.com",
                               INTERNET_DEFAULT_HTTPS_PORT, 0 );

  // 创建HTTP请求连接.
  if( hConnect )
    hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,
                                   NULL, WINHTTP_NO_REFERER, 
                                   WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                   WINHTTP_FLAG_SECURE );

  // 发送请求.
  if( hRequest )
    bResults = WinHttpSendRequest( hRequest,
                                   WINHTTP_NO_ADDITIONAL_HEADERS, 0,
                                   WINHTTP_NO_REQUEST_DATA, 0, 
                                   0, 0 );


  // 结束请求.
  if( bResults )
    bResults = WinHttpReceiveResponse( hRequest, NULL );

  // 接收数据.
  if( bResults )
  {
    do 
    {
      // 检查是否有可用数据.
      dwSize = 0;
      if( !WinHttpQueryDataAvailable( hRequest, &dwSize ) )
        printf( "Error %u in WinHttpQueryDataAvailable.\n",
                GetLastError( ) );

      // 分配空间.
      pszOutBuffer = new char[dwSize+1];
      if( !pszOutBuffer )
      {
        printf( "Out of memory\n" );
        dwSize=0;
      }
      else
      {
        // 读取数据.
        ZeroMemory( pszOutBuffer, dwSize+1 );

        if( !WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, 
                              dwSize, &dwDownloaded ) )
          printf( "Error %u in WinHttpReadData.\n", GetLastError( ) );
        else
          printf( "%s", pszOutBuffer );

        // 释放空间.
        delete [] pszOutBuffer;
      }
    } while( dwSize > 0 );
  }


  // 如果出错,输出具体错误代码.
  if( !bResults )
    printf( "Error %d has occurred.\n", GetLastError( ) );

  // 关闭所有句柄.
  if( hRequest ) WinHttpCloseHandle( hRequest );
  if( hConnect ) WinHttpCloseHandle( hConnect );
  if( hSession ) WinHttpCloseHandle( hSession );