一、相关知识

HTTP 客户端用C语言实现就是通过SOCKET 链接通道,按照HTTP协议把数据包做装好,通过SOCKET连接通道,发送,接收。我们把收到的数据按协议,拆分开,再按我梦的意愿吧没部分数据展示或存储起来就可以了。HTTP协议:https://blog.csdn.net/weixin_38087538/article/details/82838762

HTTPS 应用百度百科的解释【HTTPS 主要由两部分组成:HTTP + SSL / TLS,也就是在 HTTP 上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过 TLS 进行加密,所以传输的数据都是加密后的数据。】

简单实现HTTPS客户端也就是说我们建立一个SSL通道,然后按照HTTP协议处理数据就可以了,和HTTP客户端相比,就是把SOCKET链接通道换成SSL连接通道。那我们就要研究SSL链接通道的建立与断开。

网上搜到两幅图比较好,很容易理解SSL的建立过程。应用于:https://blog.csdn.net/Aquester/article/details/7635573

SSL客户端图

SSL服务端图

二、下载配置OpenSSL-Win64 库

然后我们需要下载 OpenSSL-Win64 库

OpenSSL-Win 主页为:https://slproweb.com/products/Win32OpenSSL.html

OpenSSL-Win64:

https://slproweb.com/download/Win64ARMOpenSSL-3_0_2.exe

https://slproweb.com/download/Win64OpenSSL-1_1_1n.exe

下载完后直接安装就可以了,一般默认配置,我的安装目录选在 D:\Program Files\OpenSSL-Win64

三、Visual Studio 配置 OpenSSL

点击项目--属性

打开属性界面,点击VC++ 目录,

"配置(C): " 选 “所有配置” ,

“平台(P):” 选 自己需要的 32 位或 64位

” 包含目录“ 添加 你 OpenSSL-Win64 安装的目录位置下的 头文件位置  D:\Program Files\OpenSSL-Win64\include

” 包含目录“ 添加 你 OpenSSL-Win64 安装的目录位置下的 lib位置  D:\Program Files\OpenSSL-Win64\lib

Visual Studio 配置 OpenSSL完成

四、撸代码

#include<tchar.h>
#include<WinSock2.h>
#include<WS2tcpip.h>
#include<iostream>
#include<openssl\ssl.h>
#include <stdio.h>
#include <windows.h>
#define BUFF_SIZE 1024
#pragma warning(disable : 4075)
#pragma warning(disable : 4996)
#pragma warning(disable : 6387)
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"libssl.lib")
#pragma comment(lib,"libcrypto.lib")CONST INT RECV_SIZE = 8192;char* UTF8ToANSI(const char* str);/*多字符转换为宽字符 --- ANSI -to- Unicode*/
wchar_t* ANSIToUnicode(const char* str)
{size_t textlen;wchar_t* result;textlen = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);result = (wchar_t*)malloc((textlen + 1) * sizeof(wchar_t));if (nullptr != (result = (wchar_t*)malloc((textlen + 1) * sizeof(wchar_t)))){memset(result, 0, (textlen + 1) * sizeof(wchar_t));MultiByteToWideChar(CP_ACP, 0, str, -1, (LPWSTR)result, textlen);return result;}return 0;
}/*宽字符转换为多字符 --- Unicode -to- ANSI*/
char* UnicodeToANSI(const wchar_t* str)
{char* result;size_t textlen;textlen = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);result = (char*)malloc((textlen + 1) * sizeof(char));if (nullptr != result){memset(result, 0, sizeof(char) * (textlen + 1));WideCharToMultiByte(CP_ACP, 0, str, -1, result, textlen, NULL, NULL);return result;}return 0;
}/*UTF8转换为宽字符 --- UTF8 -to- Unicode */
wchar_t* UTF8ToUnicode(const char* str)
{size_t textlen;wchar_t* result;textlen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);result = (wchar_t*)malloc((textlen + 1) * sizeof(wchar_t));if (nullptr != result){memset(result, 0, (textlen + 1) * sizeof(wchar_t));MultiByteToWideChar(CP_UTF8, 0, str, -1, (LPWSTR)result, textlen);return result;}return 0;
}/*宽字符转换为UTF8 --- Unicode -to- UTF8 */
char* UnicodeToUTF8(const wchar_t* str)
{char* result;size_t textlen;textlen = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);result = (char*)malloc((textlen + 1) * sizeof(char));if (nullptr != result){memset(result, 0, sizeof(char) * (textlen + 1));WideCharToMultiByte(CP_UTF8, 0, str, -1, result, textlen, NULL, NULL);return result;}return 0;
}/*多字符转换为UTF8 --- Unicode -to- UTF8 */
char* ANSIToUTF8(const char* str)
{return UnicodeToUTF8(ANSIToUnicode(str));
}/*UTF8转换为多字符 --- UTF8 -to- ANSI */
char* UTF8ToANSI(const char* str)
{return UnicodeToANSI(UTF8ToUnicode(str));
}INT _tmain(INT argc, LPTSTR argv[])
{//启初始化wsaWSADATA wsadData;if (0 != WSAStartup(MAKEWORD(2, 2), &wsadData)) {printf_s("初始化 WSAStartup 失败");return 0;}//获取Host的IP地址等信息ADDRINFOT aiHints;ZeroMemory(&aiHints, sizeof(ADDRINFOT));aiHints.ai_family = AF_INET;aiHints.ai_flags = AI_PASSIVE;aiHints.ai_protocol = 0;aiHints.ai_socktype = SOCK_STREAM;std::wstring wstrHost = TEXT("www.baidu.com");PADDRINFOT paiResult;GetAddrInfo(wstrHost.c_str(), NULL, &aiHints, &paiResult);//创建套接字SOCKET sSocket = socket(AF_INET, SOCK_STREAM, 0);if (sSocket == SOCKET_ERROR){std::wcout << "Error socket" << std::endl;return -1;}//连接HostSOCKADDR_IN sinHost{};sinHost.sin_addr = ((LPSOCKADDR_IN)paiResult->ai_addr)->sin_addr;sinHost.sin_family = AF_INET;sinHost.sin_port = htons(443);if (connect(sSocket, (LPSOCKADDR)&sinHost, sizeof(SOCKADDR_IN)) == SOCKET_ERROR){std::wcout << "Error connect" << std::endl;return -1;}//初始化OpenSSL库//(虽然不知道为什么,但是不加这三行似乎并不会导致什么问题,在不加这3行的情况下测试了几个网站并没有发现任何问题喵)SSL_library_init();                   //SSL库初始化SSLeay_add_ssl_algorithms();       //载入所有SSL算法SSL_load_error_strings();            //载入所有SSL错误消息//创建SSL会话环境等SSL_CTX* pctxSSL = SSL_CTX_new(TLS_client_method());      //产生一个SSL_CTX 数据结构if (pctxSSL == NULL){std::wcout << "Error SSL_CTX_new" << std::endl;return -1;}SSL* psslSSL = SSL_new(pctxSSL);          //产生一个SLL 数据结构if (psslSSL == NULL){std::wcout << "Error SSL_new" << std::endl;return -1;}SSL_set_fd(psslSSL, sSocket);              //将 socket 载入到 SSL 中INT iErrorConnect = SSL_connect(psslSSL);  //建立 SSL 链接if (iErrorConnect < 0){std::wcout << "Error SSL_connect, iErrorConnect=" << iErrorConnect << std::endl;return -1;}std::wcout << "SSL connection using " << SSL_get_cipher(psslSSL) << std::endl;//发包std::string strWrite ="GET https://www.baidu.com/ HTTP/1.1\r\n""Host: www.baidu.com\r\n""Connection: close\r\n\r\n";INT iErrorWrite = SSL_write(psslSSL, strWrite.c_str(), strWrite.length());       //通过SSL链接发送数据if (iErrorWrite < 0){std::wcout << "Error SSL_write" << std::endl;return -1;}//收包并输出//这里接受的是char形式的,所以中文会乱码//如果要正常显示中文,需要再转换为wchar_t或std::wstringLPSTR lpszRead = new CHAR[RECV_SIZE];INT iLength = 1;while (1 <= (iLength = SSL_read(psslSSL, lpszRead, RECV_SIZE)))        //通过SSL链接接收数据{std::cout << UTF8ToANSI(lpszRead) << std::endl;}delete[] lpszRead;SSL_shutdown(psslSSL);          //关闭 SSL 链接SSL_free(psslSSL);               //释放 SSL 数据结构体closesocket(sSocket);         //释放 SOCKETSSL_CTX_free(pctxSSL);           //释放 SSL_CTX 数据结构体return 0;
}

C 语言 https(SSL)客户端简单实现相关推荐

  1. 易语言https服务器,E2EE应用服务器套件 - 文档 - [基础教程] 使用HTTPS(SSL) - E2EE易语言网站敏捷开发框架...

    使用HTTPS(SSL) 1.申请证书 首先您需要申请SSL/TLS证书. 介绍几个免费SSL证书申请网站: 申请证书的方式网上有很多相关资料,这里就不多做说明了. 申请证书后通常会有以下三个文件: ...

  2. AFNetworking 对数据进行https ssl加密

    参考来源:http://www.cnblogs.com/jys509/p/5001566.html 现在在工作中的工作需求:https请求验证证书 一般来讲如果app用了web service , 我 ...

  3. 易语言通过服务器发送文件,易语言服务器与客户端发送文件

    易语言服务器与客户端发送文件 内容精选 换一换 PL/pgSQL是一种可载入的过程语言.用PL/pgSQL创建的函数可以被用在任何可以使用内建函数的地方.例如,可以创建复杂条件的计算函数并且后面用它们 ...

  4. EmbedTLS + Eclipse C/C++测试用例SSL客户端和服务器

    EmbedTLS + Eclipse C/C++测试用例SSL客户端和服务器 目录 EmbedTLS + Eclipse C/C++测试用例SSL客户端和服务器 (1)说明 (2)Eclipse的em ...

  5. 图文详解:阿里云域名配置免费https/SSL证书

    文章目录 https简介 证书购买 配置证书 注意事项 https简介 首先简单说一下https的原理.即服务端与客户端(浏览器)如何保证数据是加密传输的呢?我记得有个经典的例子: 服务端发给客户端一 ...

  6. python sanic 设置ssl证书_配置自签https ssl证书

    由于人们越来越重视网络安全,所以很多平台及系统都要求使用https方式接入.而且一些开源服务框架在调用时也只接受https请求,这将导致平时开发/测试时需要用到ssl证书的地方越来越多. 在2016年 ...

  7. https ssl证书的工作原理及使用相关知识收集

    https ssl证书的工作原理及使用相关知识收集 SSL 与 数字证书 的基本概念和工作原理 前言 SSL是让人头大的东西,看起来很复杂,我学过信息安全课,但是对SSL仍然是模糊一片.对于数字证书也 ...

  8. paho | 支持10种语言编写mqtt客户端,总有一款适合你!

    1. 轻量级物联网协议 - MQTT MQTT全称 Message Queuing Telemetry Transport,即消息队列遥测传输协议,是一种基于发布/订阅(publish/subscri ...

  9. ssl 客户端证书验证_SSL客户端身份验证:这是信任的问题

    ssl 客户端证书验证 [编者注:本文介绍了如何为Domino 4.6和4.6.1设置SSL客户机认证.] 互联网上最新的行业流行词是SSL. 但是SSL真正需要提供什么? 安全套接字层(SSL)是一 ...

最新文章

  1. 在SQL Server中将行有效地转换为列
  2. 内部类(innerclasses)
  3. 用自动化构建工具增强你的工作流程——gulp
  4. 添加列oracle默认值,Oracle 11g增加列,并带默认值的新特性
  5. 课堂作业-1成绩汇总
  6. CVE-2020-0601漏洞详细分析
  7. [leetcode]5325. 包含所有三种字符的子字符串数目
  8. sql随机取一条数据
  9. 考前突击!等级考试高分攻略!(整理版)
  10. linux下运行hadoop,Linux命令行下运行Hadoop单元测试
  11. qt 获取屏幕句柄_VC中获取窗口句柄的各种方法
  12. 论福禄克DTX-1800如何测试CAT7网线?
  13. 两无线路由器连接方法
  14. Spring Cloud Netflix中文文档翻译笔记
  15. 数据库字典 - 微擎开发文档
  16. TTL(生存时间)介绍
  17. his使用-重置密码
  18. Pycharm 配置 Autopep8
  19. 柏拉图团队-手把手教你发代币(二)remix入门
  20. Linux无法显示ip的解决办法

热门文章

  1. 「​MQA_HPM_CS131」XMOS 主控 MQA 解码耳放板
  2. 【专题】2022中国新能源汽车内容生态趋势洞察报告PDF合集分享(附原数据表)...
  3. 机器学习实战(二)LR算法:实现简单的分类模型
  4. 如何控制存货——浅谈
  5. html打字并自动滚动效果,js实现键盘自动打字效果
  6. 如何生成精确的调频载波和线性调频脉冲雷达测试信号?(一)
  7. 手机信号弱,怎样增强手机信号
  8. 这几天美国打下来的不明飞行物是什么?是不是外星人?
  9. 给我三分钟,带你领略热血江湖中的并查集算法
  10. excel锁定计算机,操作方法:“如何使excel或计算机屏幕上固定的任何窗口(桌面)” excle table桌面锁...