废话不多说代码中使用了两种https客户端的实现方式。完整代码https://github.com/satadriver/openssl-TLS_SSL-sample#includewindows.h#includeWinSock.h#include../include/openssl\ssl.h#include../include/openssl\err.h#pragmacomment(lib,ws2_32.lib)#pragmacomment(lib,../lib/libeay32.lib)#pragmacomment(lib,../lib/ssleay32.lib)#defineHTTPS_PORT443DWORDBIOSendRecvData(sockaddr_in stBaiduPassPortAddr,char*pSendData,intiSendSize,char*pRecvData,intiRecvSize){//ERR_load_crypto_strings();//ERR_load_SSL_strings();//OPENSSL_add_all_algorithms_noconf();//如果系统平台不支持自动进行随机数种子的设置这里应该进行设置(seed PRNG)SSL_CTX*ctxClientSSL_CTX_new(SSLv3_client_method());//通常应该在这里设置一些验证路径和模式等因为这里没有设置所以该例子可以跟使用任意CA签发证书的任意服务器建立连接BIO*stBioBIO_new_ssl_connect(ctxClient);SSL*sslClientFALSE;intiRetBIO_get_ssl(stBio,sslClient);if(sslClientFALSE){fprintf(stderr,Cant locate SSL pointer\n);//ERR_print_errors_fp(stderr);//SSL_free(sslClient);SSL_CTX_free(ctxClient);BIO_free_all(stBio);returnFALSE;}/* 不需要任何重试请求*/iRetSSL_set_mode(sslClient,SSL_MODE_AUTO_RETRY);//这里你可以添加对SSL的其它一些设置charszBioConnectAddrFormat[]%s:%u;charszBioConnectAddr[64];intiLenwsprintfA(szBioConnectAddr,szBioConnectAddrFormat,inet_ntoa(stBaiduPassPortAddr.sin_addr),HTTPS_PORT);iRetBIO_set_conn_hostname(stBio,szBioConnectAddr);//passport.baidu.com//BIO * outBIO_new_fp(stdout,BIO_NOCLOSE);if(BIO_do_handshake(stBio)0){//SSL_free(sslClient);SSL_CTX_free(ctxClient);fprintf(stderr,Error connecting to server\n);ERR_print_errors_fp(stderr);returnFALSE;}X509*stCertSSL_get_peer_certificate(sslClient);char*strServerNameX509_NAME_oneline(X509_get_subject_name(stCert),0,0);OPENSSL_free(strServerName);strServerNameX509_NAME_oneline(X509_get_issuer_name(stCert),0,0);OPENSSL_free(strServerName);X509_free(stCert);iRetBIO_write(stBio,pSendData,iSendSize);if(iRet0){//SSL_free(sslClient);SSL_CTX_free(ctxClient);BIO_free_all(stBio);returnFALSE;}char*pRecvPtrpRecvData;iRetBIO_read(stBio,pRecvPtr,iRecvSize);if(iRet0){//SSL_free(sslClient);SSL_CTX_free(ctxClient);BIO_free_all(stBio);returnFALSE;}while(iRet1){pRecvPtr;iRetBIO_read(stBio,pRecvPtr,iRecvSize);}if(iRet0){*(pRecvPtriRet)0;}BIO_free_all(stBio);SSL_CTX_free(ctxClient);//SSL_free(sslClient);//BIO_free(out);returnTRUE;}DWORDSendAndRecvHttpsPacket(sockaddr_in stBaiduPassPortAddr,char*pSendData,intiSendSize,char*pRecvData,intiRecvSize){SOCKET sockClientsocket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(sockClientINVALID_SOCKET){returnFALSE;}intiRetconnect(sockClient,(sockaddr*)stBaiduPassPortAddr,sizeof(sockaddr_in));if(iRetINVALID_SOCKET){closesocket(sockClient);returnFALSE;}SSL_CTX*pctxClientSSL_CTX_new(SSLv23_client_method());if(pctxClient0){iRetGetLastError();closesocket(sockClient);returnFALSE;}SSL*pSSLClientSSL_new(pctxClient);if(pSSLClient0){closesocket(sockClient);returnFALSE;}iRetSSL_set_fd(pSSLClient,sockClient);if(iRet0){iRetGetLastError();closesocket(sockClient);returnFALSE;}iRetSSL_connect(pSSLClient);if(iRet0){iRetGetLastError();returnFALSE;}iRetSSL_write(pSSLClient,pSendData,iSendSize);if(iRet0){iRetGetLastError();returnFALSE;}char*pRecvBufpRecvData;intiSizeiRecvSize;do{iRetSSL_read(pSSLClient,pRecvBuf,1);if(iRet0){pRecvBuf;iSize--;}}while(iRet0);*pRecvBuf0;SSL_free(pSSLClient);SSL_CTX_free(pctxClient);closesocket(sockClient);return(pRecvBuf-pRecvData);}DWORDBIOServerSample(){BIO*sbio,*bbio,*acpt,*out;intlen;chartmpbuf[1024];SSL_CTX*ctx;SSL*ssl;ERR_load_crypto_strings();ERR_load_SSL_strings();OpenSSL_add_all_algorithms();//Might seed PRNG herectxSSL_CTX_new(SSLv23_server_method());if(!SSL_CTX_use_certificate_file(ctx,server.pem,SSL_FILETYPE_PEM)||!SSL_CTX_use_PrivateKey_file(ctx,server.pem,SSL_FILETYPE_PEM)||!SSL_CTX_check_private_key(ctx)){fprintf(stderr,Error setting up SSL_CTX\n);ERR_print_errors_fp(stderr);return0;}//Might do other things here like setting verify locations and//DH and/or RSA temporary key callbacks// New SSL BIO setup as serversbioBIO_new_ssl(ctx,0);BIO_get_ssl(sbio,ssl);if(!ssl){fprintf(stderr,Cant locate SSL pointer\n);// whatever ...}// Dont want any retriesSSL_set_mode(ssl,SSL_MODE_AUTO_RETRY);// Create the buffering BIObbioBIO_new(BIO_f_buffer());//Add to chainsbioBIO_push(bbio,sbio);acptBIO_new_accept(433);// By doing this when a new connection is established// we automatically have sbio inserted into it. The// BIO chain is now swallowed by the accept BIO and// will be freed when the accept BIO is freed.BIO_set_accept_bios(acpt,sbio);outBIO_new_fp(stdout,BIO_NOCLOSE);// Setup accept BIOif(BIO_do_accept(acpt)0){fprintf(stderr,Error setting up accept BIO\n);ERR_print_errors_fp(stderr);return0;}// Now wait for incoming connectionif(BIO_do_accept(acpt)0){fprintf(stderr,Error in connection\n);ERR_print_errors_fp(stderr);return0;}// We only want one connection so remove and free// accept BIO//sbioBIO_pop(acpt);BIO_free_all(acpt);if(BIO_do_handshake(sbio)0){fprintf(stderr,Error in SSL handshake\n);ERR_print_errors_fp(stderr);return0;}BIO_puts(sbio,HTTP/1.0 200 OK\r\nContent-type: text/plain\r\n\r\n);BIO_puts(sbio,\r\nConnection Established\r\nRequest headers:\r\n);BIO_puts(sbio,--------------------------------------------------\r\n);for(;;){lenBIO_gets(sbio,tmpbuf,1024);if(len0)break;BIO_write(sbio,tmpbuf,len);BIO_write(out,tmpbuf,len);// Look for blank line signifying end of headersif((tmpbuf[0]\r)||(tmpbuf[0]\n))break;}BIO_puts(sbio,--------------------------------------------------\r\n);BIO_puts(sbio,\r\n);// Since there is a buffering BIO present we had better flush itBIO_flush(sbio);BIO_free_all(sbio);returnTRUE;}int__stdcallWinMain(__in HINSTANCE hInstance,__in_opt HINSTANCE hPrevInstance,__in LPSTR lpCmdLine,__inintnShowCmd){WSAData wsa;intretWSAStartup(0x0202,wsa);if(ret){returnFALSE;}SSL_library_init();SSL_load_error_strings();OpenSSL_add_all_algorithms();charszdata[0x4000];for(inti0;isizeof(szdata);i){szdata[i]a;}szdata[0]/;szdata[1]0;hostent*lphostgethostbyname(www.baidu.com);DWORD lpip*(DWORD*)(lphost-h_addr_list);DWORD ip*(DWORD*)lpip;sockaddr_in sa{0};sa.sin_familyAF_INET;sa.sin_portntohs(443);sa.sin_addr.S_un.S_addrip;charszrecv[0x4000];retBIOSendRecvData(sa,szdata,lstrlenA(szdata),szrecv,sizeof(szdata));//retSendAndRecvHttpsPacket(sa,szdata,0x10000,szrecv,0x10000);// SOCKET s socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);// if (s INVALID_SOCKET)// {// return FALSE;// }returnTRUE;}