您的位置:首页 > 理论基础 > 计算机网络

基于 openssl + vs2013 https客户端 Demo

2016-03-31 10:56 841 查看
环境:

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;
}


Demo附件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: