用C++创建Https客户端,用Mingw编译

用C++创建Https客户端,用Mingw编译

菜鸟一枚,本来想用C++做爬虫的,先做了一个http客户端,想要获取网页,但是发现网站的链接基本都是https,所以只好再做一个https客户端。

源码网上找的,来源为:《C/C++实现HTTPS通信(抓取百度页面)》

Https.cpp

#include <openssl/ssl.h>
#include <openssl/err.h>
 
#include <iostream>
#include <sstream>
#include <winsock2.h>
 
 
#pragma comment(lib,"libeay32.lib")
#pragma comment(lib,"ssleay32.lib")
#pragma comment(lib,"ws2_32.lib")
 
 
using namespace std;
 
int main()
{
    //加载SSL错误信息 
    SSL_load_error_strings();

    //添加SSL的加密/HASH算法 
    SSLeay_add_ssl_algorithms();

    //客户端,服务端选择SSLv23_server_method() 
    const SSL_METHOD *meth = SSLv23_client_method();

    //建立新的SSL上下文 
    SSL_CTX* ctx = SSL_CTX_new(meth);
    if(ctx == NULL)
    {
        ERR_print_errors_fp(stderr);
        cout<<"SSL_CTX_new error !";
        return -1;
    }
    
    WSADATA wsaData;
    if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
    {
        return -1;
    }

    SOCKET client = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(client == INVALID_SOCKET)
    {
        cout<<"socket error !";
        return -1;
    }
    
    string host = "www.baidu.com";
    unsigned short port = 443;
    hostent *ip = gethostbyname(host.c_str());
    
    sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    sin.sin_addr = *(in_addr*)ip->h_addr_list[0];
    
    if(connect(client,(sockaddr*)&sin,sizeof(sin)) == SOCKET_ERROR)
    {
        cout<<"connect error 1";
        return -1;
    }
    
    //建立SSL 
    int ret;
    SSL*ssl = SSL_new(ctx);
    if(ssl == NULL)
    {
        cout<<"SSL NEW error";
        return -1;
    }

    //将SSL与TCP SOCKET 连接 
    SSL_set_fd(ssl,client);

    //SSL连接 
    ret = SSL_connect(ssl);
    if(ret == -1)
    {
        cout<<"SSL ACCEPT error ";
        return -1;
    }
    
    stringstream stream;
    stream << "GET https://"<<host<<" HTTP/1.0\r\n";
    stream << "Accept: */*\r\n";
    //stream << "Accept-Encoding: gzip, deflate, br\r\n";//不要编码,否则还得多一个解码的步骤
    stream << "Accept-Language: zh-Hans-CN, zh-Hans; q=0.8, en-US; q=0.5, en; q=0.3\r\n";
    stream << "Connection: Keep-Alive\r\n";
    stream << "Host: " << host << "\r\n";
    stream << "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134\r\n";
    stream << "\r\n";
    
    string s = stream.str();
    const char *sendData = s.c_str();
    ret = SSL_write(ssl,sendData,strlen(sendData));
    if(ret == -1)
    {
        cout<<"SSL write error !";
        return -1;
    }

    char *rec = new char[1024*1024];
    int start = 0;

    while((ret = SSL_read(ssl,rec+start,1024))>0)
    {
        start += ret;
    }
    
    rec[start] = 0;
    cout<<rec;
    
    //关闭SSL套接字 
    SSL_shutdown(ssl);
    //释放SSL套接字 
    SSL_free(ssl);
    //释放SSL会话环境 
    SSL_CTX_free(ctx);
    
    closesocket(client);
    WSACleanup();
}

要实现https客户端需要学会WinSock2和OpenSSL。

  1. WinSock2学习可以参考微软的教程:《Getting Started with Winsock》

  2. OpenSSL中库的使用目前不了解,只是先确保编译通过,和能顺利抓取https网页。

  3. 用MinGw编译程序。参照这篇文章:《OpenSSL踩坑记:找到MinGW自带的OpenSSL》

    img

posted @ 2021-12-22 19:08  Lee君  阅读(343)  评论(0)    收藏  举报