加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

VC++访问https的网站

(2012-01-31 12:36:44)
分类: vc

HTTPS是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。在vc++里面我实现的方法是利用winlnet api编程

正常winlnet访问http的网站的步骤是:

1.调用InternetOpen函数           // 用来初始化一个应用程序,以使用 WinINet 函数

2.调用InternetConnect函数       //这个函数打开和指定网站的一个会话(可以是ftp/http)

3.调用HttpOpenRequest函数       //这个函数创建一个请求句柄并且把参数存储在句柄中,这个参数包括请求

                                //的动作 POST/GET/PUT 请求的子路径 如访问http://127.1/1.txt  子路

                                //径为 /1.txt 这里还有一个Flag 这里可以设置连接选项

4.调用HttpSendRequest函数        //发送http请求 消息的主体(如post的内容) 也是这个函数的一个参数

5.可以调用InternetReadFile函数   //从服务器接收返回的结果

而访问https的网站与http网站的区别:

1.在第2步打开回话的时候设定的端口 http是80 https是443

2.在第3步创建请求句柄的时候设置的Flag不同

访问http的时候可以是ConnFlag=INTERNET_FLAG_RELOAD|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_NO_CACHE_WRITE;

访问https的时候可以是ConnFlag=INTERNET_FLAG_RELOAD|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_NO_CACHE_WRITE
   |INTERNET_FLAG_SECURE|INTERNET_FLAG_IGNORE_CERT_CN_INVALID;

其余的步骤都是相同的 第4步发送的消息主体是什么内容就发什么内容,第5步接收到的也是ssl层解密后的内容,就是说除了设置端口和Flag的时候有些区别ssl层基本上是透明的

 

 

 

下面是一个能简单实现访问http/https的类

GettCon.h

// GettCon.h: interface for the GettCon class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_GETTCON_H__4B47EEFF_7202_43DD_9548_896D9198D39D__INCLUDED_)
#define AFX_GETTCON_H__4B47EEFF_7202_43DD_9548_896D9198D39D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <windows.h>// 没有这句就错了
#include <wincrypt.h>
#pragma comment (lib, "crypt32.lib")
#include <wininet.h>
#pragma   comment(lib, "wininet.lib")
#include<string>
using namespace std;
class GettCon 
{
public:
 GettCon();
 virtual ~GettCon();
 bool ConnnectToServer(string SAddr,string DPath,bool SslState,string Verb);
 string GetLastError(){ return LastError; }
 bool SendRequest(LPVOID Req,int len);
 string GettCon::GetResult();
private:
 void ClearHandles();
 string ServerAddr;
 string DestPath;
 bool SSLState;
 int  ConnFlag;
 HINTERNET m_hInternet;
 HINTERNET m_hRequest;
 HINTERNET m_hSession;
 INTERNET_PORT Port; //WORD
 string strVerb;
 string LastError;
};

#endif // !defined(AFX_GETTCON_H__4B47EEFF_7202_43DD_9548_896D9198D39D__INCLUDED_)

 

// GettCon.cpp: implementation of the GettCon class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "GettCon.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

GettCon::GettCon()
{
 ServerAddr="";
 DestPath="";
 SSLState=false;
 strVerb="";
 LastError="";
}

GettCon::~GettCon()
{

}

bool GettCon::ConnnectToServer(string SAddr,string DPath,bool SslState,string Verb)
{
 ServerAddr=SAddr;
 DestPath=DPath;
 SSLState=SslState;
 strVerb=Verb;
 if(SSLState==false)
 {
  Port=80; //http连接
  ConnFlag=INTERNET_FLAG_RELOAD|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_NO_CACHE_WRITE;
 }
 else 
 {
  Port=443; //https连接
  ConnFlag=INTERNET_FLAG_RELOAD|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_NO_CACHE_WRITE
   |INTERNET_FLAG_SECURE|INTERNET_FLAG_IGNORE_CERT_CN_INVALID;
 }
 //连接到服务器
 try
 {
  m_hInternet = InternetOpen("Not have agent", INTERNET_OPEN_TYPE_PRECONFIG , NULL, NULL, 0);
  if (!m_hInternet)
  {
   LastError = "Cannot open internet";
   return false;
  }
  m_hSession = InternetConnect(m_hInternet,ServerAddr.c_str(),Port,"","",INTERNET_SERVICE_HTTP,0,0);
  if (!m_hSession)
   
   LastError = "Cannot connect to internet";
   ClearHandles();
   return false;
  }
  m_hRequest = HttpOpenRequest(m_hSession, strVerb.c_str(),DestPath.c_str(),NULL,
   "",NULL,ConnFlag,0);
  if (!m_hRequest) {
   LastError = "Cannot perform http request";
   ClearHandles(); 
   return false;
   
 }
 catch(...) {
  LastError = "Memory Exception occured";
  return false;
 }
 return true;
}

void GettCon::ClearHandles()
{
 if (m_hInternet) {
  InternetCloseHandle(m_hInternet);
  m_hInternet = NULL;
 }
 
 if (m_hSession) {
  InternetCloseHandle(m_hSession);
  m_hSession = NULL;
 }
}
bool GettCon::SendRequest(LPVOID Req,int len)

 try
 {
  int result =  HttpSendRequest(m_hRequest,NULL,0,Req,len);
  if(result)//如果发送成功
  {
   return true;
  }
  else
  {
   LastError="Send Request Error!";
   return false;
  }
 }
 catch(...) {
  LastError = "Memory Exception occured";
  return false;
 }
}

string GettCon::GetResult()
{
 DWORD Count;
 char sz[1024];
 string strRet;
 int ret;
 do {
  ret = InternetReadFile(m_hRequest, sz, 1023, &Count);           
  sz[Count] = '\0';
  int x = strlen(sz);
  strRet += sz;
  memset(sz, 0, 1024);
  
 } while(ret && Count != 0);
 return strRet;
}

函数的使用方法

1.GettCon con;

2.调用con.ConnnectToServer(服务器IP地址,子路径,是否为https,"POST"/"GET"/"PUT");

3.调用con.SendRequest(要发送的消息主体,主体长度(字节为单位))

4.调用con.GetResult()函数获得从服务器返回的字符串

在网上有童鞋说每发送一次数据最好是把2-4步重做一遍不然容易出错,不知道是不是这样。。。。。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有