可以转载,转载请注明出处,谢谢!
关于OpenSSL的原理以及OpenSSL如何安装、使用、测试demo请参看我之前的两篇博文。
这篇博文主要实现了如何在win64下基于VS2012实现OpenSSL的非阻塞通讯。参考了以下几篇博文的内容,表示感谢:
https://blog.csdn.net/fly2010love/article/details/46470033
https://www.cnblogs.com/dongfuye/p/4121066.html
https://wiki.openssl.org/index.php/Simple_TLS_Server
其实关键步骤有以下几步:
1. 让server和client创建一般的非OpenSSL套接字的时候就设置成非阻塞的,这个应该都清楚怎么设置。
2. 因为SSL_set_fd中添加的是非阻塞的一般的套接字,所以加上一行
SSL_set_connect_state(ssl);
ssl就变成了非阻塞的。
3. SSL_connect、SSL_accept、SSL_read、SSL_write的时候注意,由于是非阻塞的,可能当前缓冲没有数据,返回是0,此时根据SSL_get_error得到错误号,如果是SSL_ERROR_WANT_WRITE或者SSL_ERROR_WANT_READ,应该直接continue,而不应该判错。这个问题实际上跟一般的winsock套接字编程一样,一般的winsock套接字在设置成非阻塞的时候,如果当前connect、accept、read、write返回是0,不见得是出错,根据WSAGetLastError可以得到错误号可能会是10035,这个错误对应的是WSAEWOULDBLOCK,表示缓冲区没数据,应该阻塞,但由于设置成非阻塞了,所以才报错。但其实也是不应该判错的,应该continue。
至于如何配置测试服务器和客户端的demo,还是请看我之前的那篇文章的介绍。现在把非阻塞版本的demo服务器和客户端代码贴下。
服务器
/*****************************************************************
*SSL/TLS服务端程序WIN32版(以demos/server.cpp为基础)
*需要用到动态连接库libeay32.dll,ssleay.dll,
*同时在setting中加入ws2_32.lib libeay32.lib ssleay32.lib,
*以上库文件在编译openssl后可在out32dll目录下找到,
*所需证书文件请参照文章自行生成.
*****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>
#include <sys/types.h>
#include <iostream>
#include <winsock2.h>
#include "openssl/rsa.h"
#include "openssl/crypto.h"
#include "openssl/x509.h"
#include "openssl/pem.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
using namespace std;
#pragma comment( lib, "ws2_32.lib" )
/*所有需要的参数信息都在此处以#define的形式提供*/
#define CERTF "server.crt" /*服务端的证书(需经CA签名)*/
#define KEYF "server.key" /*服务端的私钥(建议加密存储)*/
#define CACERT "ca.crt" /*CA 的证书*/
#define PORT 1111 /*准备绑定的端口*/
#define CHK_NULL(x) if ((x)==NULL) exit (1)
#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); }
int main ()
{
int err;
int listen_sd;
int sd;
struct sockaddr_in sa_serv;
struct sockaddr_in sa_cli;
int client_len;
SSL_CTX* ctx;
SSL* ssl;
X509*