zoukankan      html  css  js  c++  java
  • 非阻塞/异步(epoll) openssl

    前段时间在自己的异步网络框架handy中添加openssl的支持,当时在网络上搜索了半天也没有找到很好的例子,后来自己慢慢的摸索,耗费不少时间,终于搞定。因此把相关的资料整理一下,并给出简单的例子,让后学者可以少费些力气。

    同步的openssl调用网上已经有许多的例子,这里就不再详细介绍,大家也可以直接读源代码:

    同步客户端:https://github.com/yedf/openssl-example/blob/master/sync-ssl-cli.cc
    该例子连接www.openssl.com:443,发送一个Http请求,并打印结果中的前256个字符

    同步服务器端:https://github.com/yedf/openssl-example/blob/master/sync-ssl-svr.cc
    该例子监听本地的443端口,并返回一个简单http响应

    下面详细介绍非阻塞调用

    1. 初始化SSL库
    SSL_load_error_strings ();
    SSL_library_init ();
    sslContext = SSL_CTX_new (SSLv23_method ());

    //server端需要初始化证书与私钥
    string cert = "server.pem", key = "server.pem";
    r = SSL_CTX_use_certificate_file(g_sslCtx, cert.c_str(), SSL_FILETYPE_PEM);
    r = SSL_CTX_use_PrivateKey_file(g_sslCtx, key.c_str(), SSL_FILETYPE_PEM);
    r = SSL_CTX_check_private_key(g_sslCtx);


    2. 非阻塞方式建立tcp连接(网上有很多epoll相关例子)

    3. 使用已建立连接的socket初始化ssl
    ch->ssl_ = SSL_new (g_sslCtx);
    int r = SSL_set_fd(ch->ssl_, ch->fd_);
    服务器端 SSL_set_accept_state(ch->ssl_);
    客户端 SSL_set_connect_state(ch->ssl_);

    4. epoll_wait后,如果SSL相关的socket有读写事件需要处理则进行SSL握手,直到握手完成
    int r = SSL_do_handshake(ch->ssl_);
    if (r == 1) { // 若返回值为1,则SSL握手已完成
      ch->sslConnected_ = true;
      return;
    }
    int err = SSL_get_error(ch->ssl_, r);
    if (err == SSL_ERROR_WANT_WRITE) { //SSL需要在非阻塞socket可写时写入数据
      ch->events_ |= EPOLLOUT; 
      ch->events_ &= ~EPOLLIN;
    } else if (err == SSL_ERROR_WANT_READ) { //SSL需要在非阻塞socket可读时读入数据
      ch->events_ |= EPOLLIN; //等待socket可读
      ch->events_ &= ~EPOLLOUT; //暂时不关注socket可写状态
    } else { //错误
      ERR_print_errors(errBio);
    }

    5. 握手完成后,进行SSL数据的读写
    SSL_write(con->sslHandle, text, len);
    SSL_read(con->sslHandle, buf, sizeof buf);

    详细可运行的例子参看
    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

  • 相关阅读:
    【生活】我以为的周末 vs 实际上的周末
    【JS】553- 深入理解之undefined与null
    【React】552- React 中必会的 10 个概念
    【性能】551- 前端性能优化之重排和重绘
    【学习】复工至今,自我小结。你也是这样吗?
    【JS】550- 简单几步让你的 JS 写得更漂亮
    【数据结构】549- 8种常见数据结构(JS实现)
    ios 设计软件
    学习网站
    推送客户端学习网址
  • 原文地址:https://www.cnblogs.com/dongfuye/p/4121066.html
Copyright © 2011-2022 走看看