SSL_shutdown返回值的研究(2)

本文详细解析了 SSL_shutdown 函数的工作原理及使用方法。重点介绍了该函数如何支持单向和双向关闭过程,并通过示例代码展示了正确的调用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Analyze:
According to the conclusion(1)of return value of SSL_shutdown:
a.Return code 0 indicates that the application issued the SSL_shutdown function first. Continue issuing the SSL_shutdown function until you receive return code 1, which indicates the remote application has also shut down.

    b.SSL_shutdown() supports both uni- and bidirectional shutdown by its 2
step behaviour. c.When the application is the first party to send the "close notify" alert, SSL_shutdown() will only send the alert and the set the SSL_SENT_SHUTDOWN flag (so that the session is considered good and willbe kept in cache). SSL_shutdown() will then return with 0. If a unidi-rectional shutdown is enough (the underlying connection shall be closed anyway), this first call to SSL_shutdown() is sufficient. In order to complete the bidirectional shutdown handshake, SSL_shutdown() must be called again. The second call will make SSL_shutdown() wait for the peer's "close notify" shutdown alert. On success, the second call to SSL_shutdown() will return with 1.
2.sample:
ret = SSL_shutdown(ssl);/*First call*/
printf("line=%d,ret=%d\n",__LINE__,ret);
if(ret != 1)
SSL_shutdown(ssl);/*Call again*/
done:
/*end socket */
close(sockfd);
SSL_free(ssl);
SSL_CTX_free(ctx);
ERR_free_strings();
将如下代码改成一个函数#include <string.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <openssl/ssl.h> #include <openssl/err.h> #define MAX_BUF_SIZE 1024 int main(int argc, char *argv[]) { int sockfd, ret; char *url = argv[1]; // 输入的 url char *cert_path = argv[2]; // 输入的证书路径 struct sockaddr_in servaddr; SSL_CTX *ctx; SSL *ssl; char buf[MAX_BUF_SIZE]; // 初始化 SSLSSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); // 创建 SSL 上下文 ctx = SSL_CTX_new(TLS_client_method()); if (ctx == NULL) { printf("SSL_CTX_new error.\n"); return -1; } // 加载证书 ret = SSL_CTX_load_verify_locations(ctx, cert_path, NULL); if (ret != 1) { printf("SSL_CTX_load_verify_locations error.\n"); return -1; } // 创建 socket sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { printf("socket error.\n"); return -1; } // 设置服务器地址 memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(443); inet_pton(AF_INET, url, &servaddr.sin_addr); // 连接服务器 ret = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); if (ret < 0) { printf("connect error.\n"); return -1; } // 创建 SSL 对象 ssl = SSL_new(ctx); if (ssl == NULL) { printf("SSL_new error.\n"); return -1; } SSL_set_fd(ssl, sockfd); // 建立 SSL 连接 ret = SSL_connect(ssl); if (ret != 1) { printf("SSL_connect error.\n"); return -1; } // 发送请求 char *request = "GET / HTTP/1.1\r\nHost: %s\r\n\r\n"; sprintf(buf, request, url); SSL_write(ssl, buf, strlen(buf)); // 接收响应 while (1) { memset(buf, 0, sizeof(buf)); ret = SSL_read(ssl, buf, sizeof(buf) - 1); if (ret < 0) { printf("SSL_read error.\n"); break; } else if (ret == 0) { break; } else { printf("%s", buf); } } // 关闭 SSL 连接 SSL_shutdown(ssl); SSL_free(ssl); // 关闭 socket close(sockfd); // 清理 SSL 上下文 SSL_CTX_free(ctx); return 0; }
05-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值