基于 openssl + vs2013 https客户端 Demo

环境:

win7 + vs2013 + openssl-1.0.2f

openssl-1.0.2f 采用 lib 编译

注意:

设置 工程的包含目录 到 编译好的openssl 的 \include\openssl目录下

在 vc++ 目录 包含目录中填入

$(ProjectDir)\openssl( 这个可能不是你的目录名 )\include

代码 一部分来自 openssl 自带的demo 一部分直接从 msdn 上面剪下来

注意关闭 项目==》属性==》SDL 检查 以忽略gethostbyname 错误


// HttpsCliDemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"


#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")

#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#pragma comment(lib,"./openssl/lib/libeay32.lib")
#pragma comment(lib,"./openssl/lib/ssleay32.lib")


#define HOST        "www.mail.163.com"

// 手工构造最简单的请求包   
// Ps.
// 如果没有此字段,请求成功后不会立刻断开
// Connection:closed\r\n 
#define REQUEST     "GET / HTTP/1.1\r\nHost: mail.163.com\r\nConnection:closed\r\n\r\n"



int _tmain(int argc, _TCHAR* argv[])
{


    int nStarup, nErr = 0;
    WSADATA wsaData;
    SOCKET sConnectSocket = -1;

    char szResponseBuf[40960];

    __try
    {
        // 1. 初始化WSA 和 Openssl Lib
        nStarup = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (nStarup != NO_ERROR) {
            wprintf(L" WSAStartup function failed with error: %d\n", nStarup);
            __leave;
        }
        SSLeay_add_ssl_algorithms();
        SSL_load_error_strings();



        // 2. 创建套接字并连接服务器
        sConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sConnectSocket == INVALID_SOCKET) {
            wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
            WSACleanup();
            __leave;
        }

        hostent* host = (hostent*)gethostbyname(HOST);
        struct in_addr **addr_list = (struct in_addr **)host->h_addr_list;
        sockaddr_in clientService;

        clientService.sin_family = AF_INET;
        clientService.sin_addr.s_addr = inet_addr(inet_ntoa(*addr_list[0]));
        clientService.sin_port = htons(443);

        nStarup = connect(sConnectSocket, (SOCKADDR *)& clientService, sizeof(clientService));
        if (nStarup == SOCKET_ERROR)
        {
            wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
            nStarup = closesocket(sConnectSocket);
            if (nStarup == SOCKET_ERROR)
            {
                wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
            }
            sConnectSocket = 0;
            WSACleanup();
            __leave;
        }

        // 3. 初始化加密模式生成ssl套接字
        SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());
        if (!ctx)
        {
            wprintf(L"SSL_CTX_new failed\n");
            nStarup = closesocket(sConnectSocket);
            if (nStarup == SOCKET_ERROR)
            {
                wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
            }
            sConnectSocket = 0;
            WSACleanup();
            __leave;
        }
        SSL *ssl = SSL_new(ctx);
        if (!ssl)
        {
            SSL_CTX_free(ctx);

            wprintf(L"SSL_new failed\n");
            nStarup = closesocket(sConnectSocket);
            if (nStarup == SOCKET_ERROR)
            {
                wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
            }
            sConnectSocket = 0;
            WSACleanup();       
            __leave;
        }

        // 4. 绑定 原套接字到 ssl套接字
        nErr = SSL_set_fd(ssl, sConnectSocket);

        // 5. 使用ssl套件字建立连接
        nErr = SSL_connect(ssl);

        // 6. Request https server
        nErr = SSL_write(ssl, REQUEST, strlen(REQUEST));
        wprintf(L"\n===============读取网页==================");
        // 7. 由于控制台缓存区不够可能打印不完整
        do
        {
            ZeroMemory(szResponseBuf, sizeof(szResponseBuf));
            nErr = SSL_read(ssl, szResponseBuf, sizeof(szResponseBuf));
            if (nErr > 0) {
                printf("%s", szResponseBuf);
            }
            else
            {       
                break;
            }
        } while (true);

        // 8. 释放    
        SSL_free(ssl);
        SSL_CTX_free(ctx);

        nStarup = closesocket(sConnectSocket);
        if (nStarup == SOCKET_ERROR)
        {
            wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
        }
        sConnectSocket = 0;
        WSACleanup();
        wprintf(L"\n=======================================\n");
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        wprintf(L"find exception!\n");
    }
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值