c语言实现https客户端 源码+详细注释(OpenSSL下载,visual studio编译器环境配置)

OpenSSL的下载和环境配置

请参考:openssl下载安装教程
步骤:官网下载->安装到选定目录->配置环境变量->打开命令窗口检查是否安装成功
注意:
打开命令窗口(快捷键win+r,在弹出窗口内输入cmd按回车),输入命令openssl version如果显示openssl版本则表示安装成功。
我出现的问题:明明安装上了却显示

B:>openssl version
‘openssl’ 不是内部或外部命令,也不是可运行的程序
或批处理文件。

解决方法:更改到lib目录,输入命令:

B:\OpenSSL-Win64\lib>openssl.exe

因为我的版本openssl.exe文件在lib目录下,可以在OpenSSL-Win64文件夹里直接搜索openssl.exe,就知道在哪个目录下了。
运行之后再输入openssl version就会显示版本,例:

B:\OpenSSL-Win64\bin>openssl version
OpenSSL 3.1.0 14 Mar 2023 (Library: OpenSSL 3.1.0 14 Mar 2023)

出现版本信息代表安装成功。

visual studio项目环境配置

我使用visual studio2019版本,以下步骤仅供参考。
1.在属性页顶端右边,把平台改成x64(根据自己需要),点击右侧配置管理器按钮,将此项目的平台改成x64(根据自己需要)。
2.打开项目界面,在上方菜单栏选择项目->属性
3.在左侧选择VC++目录,选择包含目录,编辑,粘贴openssl的include目录的绝对路径。

例如:B:\OpenSSL-Win64\include

选择库目录,编辑,粘贴openssl的lib目录的绝对路径

例如:B:\OpenSSL-Win64\lib

4.选择左侧C/C++常规,选择附加包含目录,编辑,粘贴openssl的include目录的绝对路径。

例如:B:\OpenSSL-Win64\include

5.选择左侧链接器,选择下侧输入,选择右侧附加依赖项,编辑,写入libssl.lib,libcrypto.lib的路径。在lib目录中,打开自己下载的openssl文件夹看一下具体是哪个路径,不同版本可能不同,我使用的版本是 3.1.0 14

例如:
B:\OpenSSL-Win64\lib\libssl.lib
B:\OpenSSL-Win64\lib\libcrypto.lib

注意:编译器所有无法识别SSL…的问题都是环境没配置好,再仔细看一下上述步骤,都是一步步配置过的,亲测OK。

代码实现

思路

请添加图片描述

源码

#include<stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h> 
#include <openssl/ssl.h>
#pragma comment(lib, "Ws2_32.lib")
int main() {// 初始化 Winsock(windows套接字)/*WSADATA是windows API定义的一个结构,存储关于winsock实现的详细信息*/WSADATA wsaData;/*WSAStartup()这个函数用于初始化Winsock库,MAKEWORD(2, 2)相当于创建了一个对Winsock 2.2的版本请求,&wsaData用于将wsaData地址结构传入函数*/if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {/*WSAStartup返回了一个非0的值则代表初始化失败*/printf("WSAStartup failed\n");return 1;}printf("客户端Winsock初始化成功\n");printf("————————————————————\n");//创建客户端对象/*声明一个整型变量socket_fd用来存储套接字描述符*/int socket_fd;/*socket()函数用于创建一个新的套接字,AF_INET指定了地址族为ipv4,SOCK_STREAM指定了套接字类型为流式套接字,即TCP第三个参数,通常用来指定协议*/if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== 0){perror("socket failed");exit(EXIT_FAILURE);}/*声明一个结构体变量sock_addr,用于存储套接字地址信息(IPv4)*/struct sockaddr_in sock_addr;	sock_addr.sin_family = AF_INET; //使用ipv4地址族/*htons() 函数用于将主机字节顺序转换为网络字节顺序,确保在不同架构的计算机上,端口号的表示都是一致的。*/sock_addr.sin_port = htons(8080); //设置端口号为8080//设置网络ip/*调用inet_pton()函数将字符串形式的IP地址转换为网络字节序的二进制IP地址,并存储到sock_addr.sin_addr中*/if (inet_pton(AF_INET, "192.168.1.128", &sock_addr.sin_addr) <= 0) {/*inet_pton()函数返回值如果小于等于零,表示转换失败*/perror("inet_pton() failed");exit(EXIT_FAILURE);}printf("创建客户端对象成功,尝试连接服务器\n");printf("————————————————————\n");//连接服务器if ((connect(socket_fd, (struct sockaddr*)&sock_addr, sizeof(sock_addr)) < 0)) {perror("connect failed\n");exit(EXIT_FAILURE);}printf("对服务器发起连接\n");//初始化openssl库//SSL库初始化SSL_library_init();//载入所有SSL算法SSLeay_add_ssl_algorithms();//载入所有SSL错误消息SSL_load_error_strings();//创建SSL会话环境//使用 TLS_client_method() 函数创建了一个 SSL 上下文结构(SSL_CTX)/*TLS_client_method()const SSL_METHOD *TLS_client_method(void);函数的返回值用于指定SSL/TSL连接使用的方法,这个方法指定了客户端如何与服务器端建立连接。通过调用该函数,获取一个用于SSL/TSL客户端的SSL_METHOD结构,这个结构被传递给SSL_CTX_new()函数,用于创建SSL_CTX上下文对象。SSL_CTX_new()SSL_CTX *SSL_CTX_new(const SSL_METHOD *method);根据指定的SSL/TLS方法创建一个SSL/TSL上下文对象,该上下文对象包含了SSL/TSL连接的所有配置信息,包括加密算法、证书、私钥等。若创建失败返回NULL。*/SSL_CTX* pctxSSL = SSL_CTX_new(TLS_client_method());if (pctxSSL == NULL) {printf("error ssl_ctx_new\n");return -1;}/*基于之前创建的 SSL 上下文(SSL_CTX),创建了一个 SSL 对象,该对象将使用指定的上下文对象来配置 SSL/TLS 连接*/SSL* psslSSL = SSL_new(pctxSSL);if (psslSSL == NULL) {printf("error ssl_new\n");}/*SSL_set_fd()函数用于将一个套接字文件描述符与SSL对象关联起来,从而使SSL对象可以在该套接字上进行SSL/TSL加密通信。*/SSL_set_fd(psslSSL, socket_fd);//使用之前创建的 SSL 结构(SSL),建立了 SSL 连接。/*SSL_connect()函数尝试与远程服务器建立安全连接。iErrorConnect表示连接的状态,如果连接失败返回值小于零。*/INT iErrorConnect = SSL_connect(psslSSL);if (iErrorConnect < 0) {//打印错误码printf("error SSL_connect,iErrorConnect=%d\n", iErrorConnect);//打印当前SSL连接所使用的加密算法/*SSL_get_cipher() 函数返回一个指向当前 SSL 连接所使用的加密算法字符串的指针。*/}/*SSL_get_cipher() 函数返回一个指向当前 SSL 连接所使用的加密算法字符串的指针。*/printf("SSL connection using:%s\n", SSL_get_cipher(psslSSL));//准备http请求char http[] = "GET /index.html HTTP/1.1\r\nHost: 192.168.10.124:8080\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nMozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36\r\ntext/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n";//通过SSL连接发送http get请求,发送成功则返回发送的字节数,否则返回一个负值表示发送失败/*SSL_write()函数用于在SSL连接上写入数据,将http中的数据写入到与psslSSL相关的SSL连接中* 返回值小于零表示写入失败*/INT iErroeWrite = SSL_write(psslSSL,http,strlen(http));if (iErroeWrite<0) {printf("error SSL_write\n");return -1;}char buf[2048] = {0};/**/INT iLength = 1;/*调用SSL_read函数从SSL连接中读取数据第一个参数:SSL连接对象第二个参数:指向接收缓冲区的指针第三个参数:缓冲区的大小函数返回读取到的字节数*/while ((iLength=SSL_read(psslSSL,buf, sizeof(buf)))>=1) {}printf("读取数据成功\n");printf("服务器端给出的回应是%s\n", buf);//关闭SSL连接SSL_shutdown(psslSSL);//释放SSL数据结构SSL_free(psslSSL);//释放SSL_CTX数据结构SSL_CTX_free(pctxSSL);//关闭套接字closesocket(socket_fd);WSACleanup();return 0;
}

参考链接

1.c语言https实现客户端
2.visual studio openssl环境配置
3.https协议详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/541941.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker 学习笔记

Docker 1. 初识 Docker 快速构建、运行、管理应用的工具 1.1 安装 删除已有的 docker 版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine安装所需的软件包 首…

2024/03/15(网络编程·day3)

一、思维导图 二、模拟面试题 什么是IP地址&#xff1f; IP地址是主机在网络中的唯一标识。 分为IPv4和IPv6&#xff0c; IPv4由4字节32位二进制数组成&#xff0c;通常使用点分十进制表示&#xff0c;例如192.168.117.85 &#xff0c;其中每个十进制数的范围都在0-255. IPv6由…

【解读】Synopsys发布2024年开源安全和风险分析报告OSSRA

软件供应链管理中&#xff0c;许可证和安全合规性至关重要。开源组件和库可降低风险&#xff0c;但需了解许可证内容。Synopsys 2023年审计发现&#xff0c;超过一半的代码库存在许可证冲突。MIT许可证是最常用的宽松许可证&#xff0c;但也与其他许可证存在不兼容风险。点此获…

Android SystemServer进程解析

SystemServer进程在android系统中占了举足轻重的地位&#xff0c;系统的所有服务和SystemUI都是由它启动。 一、SystemServer进程主函数流程 1、主函数三部曲 //frameworks/base/services/java/com/android/server/SystemServer.java /** * The main entry point from zy…

51单片机LED8*8点阵显示坤坤跳舞打篮球画面

我们作为一名合格的 ikun&#xff0c;专业的小黑子&#xff0c;这个重要的知识必须学会。 先看效果&#xff1a; 51LED点阵_鸡你太美 这里我们首先要用到延时函数Delay&#xff1a; void Delay(unsigned int xms) {unsigned char i, j;while(xms--){ i 2;j 239;do{while (-…

AWS云上面的k8s统一日志收集(Fluent Bit+EKS+CW)

目标 k8s上面的常见的统一日志方案是EFK&#xff0c;具体如下&#xff1a; E:elasticsearch;F:fluentd;K:kibana 这里我们变成了使用fluentd的AWS替代品Fluent Bit&#xff0c;直接将日志输出到CloudWatch组。不需要E和K了。不过&#xff0c;这样仅仅用于AWS EKS。 步骤 给…

Scala--01--简介、环境搭建

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1. Scala简介1.1 Scala是什么&#xff1f;官网&#xff1a; [https://scala-lang.org/](https://scala-lang.org/)官方文档&#xff1a; [https://docs.scala-lang.…

工具-百度云盘服务-身份认证

目标 通过百度网盘API的方式去获取网盘中的文件&#xff0c;要实现这的第一步就是需要获取网盘的权限。资料(参考) 如果期望应用访问用户的网盘文件&#xff0c;则需要经过用户同意&#xff0c;这个流程被称为“授权”。百度网盘开放平台基于 OAuth2.0 接入授权。OAuth2.0 是…

Tomcat不识别请求路径中的特殊字符{}

报错内容解决方法1 /opt/tomcat/conf/catalina.properties --> tomcat.util.http.parser.HttpParser.requestTargetAllow|{} 解决方法2 /opt/tomcat/conf/server.xml --> relaxedQueryChars"[]|{}-^&#x60;&quot;<>" relaxedPathChars"[]|{…

分布式CAP理论

CAP理论&#xff1a;一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;和分区容错性&#xff08;Partition tolerance&#xff09;。是Eric Brewer在2000年提出的&#xff0c;用于描述分布式系统基本性质的定理。这三个性质在分布式系统…

193基于matlab的基于两轮驱动机器人的自适应轨迹跟踪算法

基于matlab的基于两轮驱动机器人的自适应轨迹跟踪算法&#xff0c;将被跟踪轨迹分段作为跟踪直线处理&#xff0c;相邻离散点之间为一段新的被跟踪轨迹。程序已调通&#xff0c;可直接运行。 193 自适应轨迹跟踪算法 两轮驱动机器人 - 小红书 (xiaohongshu.com)

ftp和fxp哪个传传输快,传输大文件该怎么选择?

在当今数字化时代&#xff0c;大文件传输已成为日常工作和商业活动中不可或缺的一部分。无论是跨国公司的数据交换&#xff0c;还是个人用户的大型媒体文件分享&#xff0c;选择一个高效的传输协议至关重要。FTP和FXP是两种常用的文件传输方式&#xff0c;但在传输大文件时&…