非阻塞openssl

前段时间在自己的异步网络框架handy中添加openssl的支持,因此把相关的资料整理一下,并给出简单的例子

先看同步的openssl使用

客户端的调用次序为:
//初始化SSL库
SSL_load_error_strings ();
SSL_library_init ();
sslContext = SSL_CTX_new (SSLv23_client_method ());

//连接tcp
con->socket = connect (handle, (struct sockaddr *) &server,
sizeof (struct sockaddr));
//初始化一个SSL结构,并与tcp关联
con->sslHandle = SSL_new (sslContext);
SSL_set_fd (con->sslHandle, con->socket);

//调用SSL_connect进行SSL握手
SSL_connect (con->sslHandle);

//通过SSL_read,SSL_write来读写SSL连接里的数据
SSL_write (con->sslHandle, text, len);
SSL_read(con->sslHandle, buf, sizeof buf);
详细可运行的例子参看
https://github.com/yedf/openssl-example/blob/master/sync-ssl-cli.cc
该例子连接www.openssl.com:443,发送一个Http请求,并打印结果中的前256个字符

服务器端调用次序为:
//初始化SSL库
SSL_library_init();
SSL_load_error_strings(); 
ERR_load_BIO_strings(); 
SSL_CTX* ctx = SSL_CTX_new (SSLv23_method());

//设置证书与私钥
int r = SSL_CTX_use_certificate_file(ctx, "server.pem", SSL_FILETYPE_PEM);
r = SSL_CTX_use_PrivateKey_file(ctx, "server.pem", SSL_FILETYPE_PEM);

//进行tcp监听与接收连接
int nListenFd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, 0);
r = bind(nListenFd, (struct sockaddr *)&addr, len);
r = listen(nListenFd, 20);
int nAcceptFd = accept(nListenFd, (struct sockaddr *)&addr, (socklen_t *)&len);

//根据tcp socket来初始化SSL
SSL* ssl = SSL_new (ctx);
SSL_set_fd (ssl, nAcceptFd);

//进行SSL握手,下面两个调用可以用SSL_accept(ssl)来替换
SSL_set_accept_state(ssl);
r = SSL_do_handshake(ssl);

//通过SSL_read, SSL_write进行读写
SSL_read(ssl,szBuffer, sizeof(szBuffer)); 
const char* resp = "HTTP/1.1 200 OK\r\nConnection: Close\r\n\r\n";
SSL_write(ssl, resp, strlen(resp));

详细可运行的例子参看
https://github.com/yedf/openssl-example/blob/master/sync-ssl-svr.cc
该例子监听本地的443端口,并返回一个简单http响应

非阻塞调用

非阻塞调用与同步调用的主要区别在于握手过程并不能够一次性完成,当tcp连接建立之后,调用SSL_set_accept_state/SSL_set_connect_state, 然后在socket可读可写的时候调用SSL_do_handshake直到该调用返回1,一旦SSL握手完成之后,那么把原先socket中的read/write替换成SSL相关函数即可。

详细可运行的例子参看
https://github.com/yedf/openssl-example/blob/master/async-ssl-svr.cc
https://github.com/yedf/openssl-example/blob/master/async-ssl-cli.cc

handy已经对openssl进行了封装,并且给出了例子,详见
https://github.com/yedf/handy-ssl

时间: 2024-11-10 02:35:43

非阻塞openssl的相关文章

透过现象看本质——回头再看Nginx(进程模型、异步非阻塞、源码目录结构)

透过现象看本质--回头再看Nginx Nginx的进程模型 ? 使用过nginx的朋友都知道nginx的性能很高,而其原因可能少有人知.首先,nginx的架构就奠定了其高性能的基础.那么就先来看看nginx的基础架构吧,如下图所示:(不能完全理清楚所有内容也没关系,因为本小节讲述的主要内容是Nginx的进程模型) ? 本小节先来说说Nginx基础架构中的进程模型: ? 所谓进程模型,即Nginx响应请求或服务时程序运行(机器执行指令集)的方式,一般在nginx服务启动后,在Unix系统中会以da

Java NIO实现非阻塞式socket通信

博主知识水平有限,只能提供一个个人的狭隘的理解,如果有新人读到这儿,建议看一下其他教程或者API,如果不明白,再来看一下:如果有dalao读到这儿,希望能指出理解中的问题~谢谢 Java提供了用于网络通信的socket和serversocket包,然而实现方式是阻塞式的,同一时间点上只能进行一个连接,这会带来不好的体验.当然了,我们也可以通过不断创建线程的方式管理连接,但线程多了的话反而会降低效率.于是Java推出了非阻塞式IO--channel.并且channel提供关于网络通信的相关chan

Windows 非阻塞或异步 socket

异步与非阻塞区别见我的另外一篇文章Socket 同步/异步与阻塞/非阻塞区别 select WSAAsyncSelect WSAEventSelect 重叠(Overlapped)I/O IOCP:完成端口 Select 首先要使用ioctlsocket设置为非阻塞模式. 然后启动线程,线程中不停select. WSAAsyncSelect WSAAsyncSelect模型是Windows下最简单易用的一种Socket I/O模型.使用这种模型时,Windows会把网络事件以消息的形势通知应用程

理解同步异步与阻塞非阻塞

本篇文章我准本从三个大方面来解释下同步异步.阻塞非阻塞的知识,第一个方面主要是说下,到底什么是同步异步.阻塞非阻塞:第二个方面主要是解释下在I/O场景下,同步异步阻塞非阻塞又是怎么定义的,第三个方面介绍下在unix下同步异步又有哪些阻塞非阻塞IO. 1.同步异步与阻塞非阻塞 首先从大的方面来说,"阻塞"与"非阻塞"与"同步"与"异步"不能简单的从字面理解,提供一个从分布式系统角度的回答. 1).同步与异步 同步和异步关注的是消

Java多线程之~~~线程安全容器的非阻塞容器

在并发编程中,会经常遇到使用容器.但是如果一个容器不是线程安全的,那么他在多线程的插入或者删除的过程 中就会出现各种问题,就是不同步的问题.所以JDK提供了线程安全的容器,他能保证容器在多线程的情况下安全的插 入和删除.当然,线程安全的容器分为两种,第一种为非阻塞似的,非阻塞的意思是当请求一个容器为空或者这个请求 不能执行的时候,就会报出异常,第二种阻塞的意思是,不能执行的命令不会报出异常,他会等待直到他能执行.下面 我们实现一个例子,这个例子就是多个线程去大量的插入容器数据,而另一个线程去大量

同步/异步与阻塞/非阻塞

一.同步与异步同步/异步, 它们是消息的通知机制 1. 概念解释A. 同步所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回. 按照这个定义,其实绝大多数函数都是同步调用(例如sin isdigit等).但是一般而言,我们在说同步.异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务.最常见的例子就是 SendMessage.该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回.当对方处理完毕以后,该函数才把消息处理函数所返回的值返回给调用者. B.

时间获取程序客户端 TCP 使用非阻塞connect

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie /** * TCP,使用非阻塞 connect **/ #include "unp.h" int connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec) { int flags, n, error; socklen_t len; fd_set rset, wset; struct timeval t

非阻塞模式(ioctlsocket)

1 //Server.cpp 2 #include <stdio.h> 3 #include <winsock2.h> //winsock.h (2种套接字版本) 4 #pragma comment(lib,"ws2_32.lib") //wsock32.lib 5 6 #define MAXSIZE 100 // 7 8 int main() 9 { 10 // 11 int retVal; 12 13 char buf[MAXSIZE]; 14 15 //初

非阻塞IO服务器模型

我们来考虑一个情形,你跟千千万万个玩家是魔兽世界的超级粉丝,每周末准时组团打boss.每当周末游戏服务器就亚历山大,因为起码几十万用户同时在线.如果用我们的多线程阻塞服务器作为游戏服务器是否可行呢?先分析游戏服务器有哪些特点: ①  网络游戏并非像网页一样,打开一旦下载完就可以关闭连接结束.网游必须是有一个持久有状态的连接,每一个客户端都需要跟服务器存在一个持久的连接,以便快速及时发送消息.而随着并发用户数量的增加,多线程阻塞服务器不可能为每一个客户端分配一个线程. ②  跟一般的应用服务器不同