C/C++實現HTTPS通訊(抓取百度頁面)
阿新 • • 發佈:2018-12-11
#include <WINSOCK2.H> #include <openssl/ssl.h> #include <openssl/err.h> #include <iostream> #include <sstream> #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(); }