最近测试广州电信的电话会议平台,该平台接入采用HTTPS协议,于是有了本文。09年培训时写过一个简单的TLS C/S结构交互,采用openssl的ssl相关接口,但与生产相去胜远。本文采用openssl提供的BIO。

长链接还是短链接?

测试过程中发现长连接在一段时间内没有数据交互会被服务方释放,无法重新连接。根据自身业务选择。

BIO设置为阻塞还是非阻塞?

本场景下都为http同步请求,故设置为阻塞。代码实现时必须考虑阻塞的等待时间(测试结果是默认阻塞BIO为60s超时)对性能和业务的影响。

读写出错控制

如果写出错,需要校验BIO_should_retry,如果为true,需等待片刻后重新写,阻塞的BIO一般不会出现;

如果读出错,同样要校验BIO_should_retry,非阻塞的BIO可能会影响性能。

相关头文件:

#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
/* Initializing OpenSSL */
SSL_library_init();
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms(); SSL_CTX *m_ctx =SSL_CTX_new(SSLv23_client_method());
if (m_ctx == NULL)
{
exit(1);
}
//加载pem 该pem是openssl源码库里自带的
if(! SSL_CTX_load_verify_locations(m_ctx, "./certs/demo/ca-cert.pem", NULL))
{
exit(1);
}

下面四个函数封装了BIO的创建、释放、读和写,可以满足基本的需求了。


BIO *
bio_new ()
{
  SSL *ssl;
  BIO *bio = BIO_new_ssl_connect (m_ctx);
  BIO_get_ssl (bio, &amp;
           ssl);
  if (!ssl)
    {
      BIO_free_all (bio);
      return NULL;
    }
  SSL_set_mode (ssl, SSL_MODE_AUTO_RETRY);    //自动重试
  BIO_set_conn_hostname (bio, "xxx.com:443");
  if (BIO_do_connect (bio) & lt; = 0)
    {
      BIO_free_all (bio);
      return NULL;
    } //校验失败是非致命的
  if (SSL_get_verify_result (ssl) != X509_V_OK)
    {
      /* Handle the failed verification */
    }   if (BIO_do_handshake (bio) & lt; = 0)
    {                //ssl握手
      BIO_free_all (bio);
      return NULL;
    }
  return bio;
} int
bio_write (BIO * bio, const char *buf, int len)
{
  if (buf == NULL)
    {
      return PROC_FAILED;
    }
  if (BIO_write (bio, buf, len) & lt; = 0)
    {
      if (!BIO_should_retry (bio))
    {
/* Handle failed write here */
      return PROC_FAILED;
    }
/* Do something to handle the retry */
      return PROC_FAILED;
    }
  return PROC_SUCCESS;
} int
bio_read (BIO * bio, char *buf, int len)
{
  if (buf == NULL)
    {
      return PROC_FAILED;
    }
  int x = BIO_read (bio, buf, len);
  if (x == 0)
    {
/* Handle closed connection */
      return PROC_FAILED;
    }
  else if (x & lt; 0)
    {
      if (!BIO_should_retry (bio))
    {
/* Handle failed read here */
      return PROC_FAILED;
    }
/* Do something to handle the retry */
      return PROC_FAILED;
    }
  return x;
} int
bio_close (BIO * bio)
{
  if (bio != NULL)
    BIO_free_all (bio);
  return PROC_SUCCESS;
} BIO * bio = bio_new ();
if (bio == NULL)
  {
    return PROC_FAILED;
  } //发送数据
if (bio_write (bio, buff, strlen (buff)) == PROC_FAILED)
  {
    bio_close (bio);
    return PROC_FAILED;
  } char response[8192] = { 0x00 }; int len = 0; //接收数据 if ((len = bio_read (bio, response, 8192)) == PROC_FAILED)
  {
    bio_close (bio);
    return PROC_FAILED;
  }
bio_close (bio);

参考资料:

https://www.openssl.org/docs/crypto/BIO_f_ssl.html

https://www.openssl.org/docs/crypto/BIO_should_retry.html

另:BIO也很多种类型,感觉功能很强大,本人c++菜鸟,没仔细研究...

TLS编程的更多相关文章

  1. TLS学习总结

    我们有知道 Immunity Debugger,OD 调试器,在调试程序时会设断在OEP(修改第一个字节0xcc).我在想,使用什么编程技术,代码可以在OEP前被执行.在网上找了些资料,在论坛上看到许 ...

  2. Apache Mina原理及典型例子分析

    Apache Mina ,一个高性能 Java 异步并发网络通讯框架.利用 Mina 可以高效地完成以下任务: TCP/IP 和 UDP/IP 通讯 串口通讯 VM 间的管道通讯 SSL/TLS JX ...

  3. Android网络编程系列 一 JavaSecurity之JSSE(SSL/TLS)

    摘要:     Java Security在Java存在已久了而且它是一个非常重要且独立的版块,包含了很多的知识点,常见的有MD5,DigitalSignature等,而Android在Java Se ...

  4. 【windows核心编程】线程局部存储TLS

    线程局部存储TLS, Thread Local Storage TLS是C/C++运行库的一部分,而非操作系统的一部分. 分为动态TSL 和 静态TLS 一.动态TLS 应用程序通过调用一组4个函数来 ...

  5. 异步编程系列第05章 Await究竟做了什么?

    p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提 ...

  6. 浅谈 HTTPS 和 SSL/TLS 协议的背景与基础

    来自:编程随想   >> 相关背景知识 要说清楚 HTTPS 协议的实现原理,至少需要如下几个背景知识. 大致了解几个基本术语(HTTPS.SSL.TLS)的含义 大致了解 HTTP 和 ...

  7. TLS 与 python thread local

    TLS 先说TLS( Thread Local Storage),wiki上是这么解释的: Thread-local storage (TLS) is a computer programming m ...

  8. 牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结 转载

    基础篇:操作系统.计算机网络.设计模式 一:操作系统 1. 进程的有哪几种状态,状态转换图,及导致转换的事件. 2. 进程与线程的区别. 3. 进程通信的几种方式. 4. 线程同步几种方式.(一定要会 ...

  9. Node.js高级编程读书笔记Outline

    Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...

随机推荐

  1. easyUI的form表单重复提交处理

    1. 问题 生产环境出现过新增用户提交, 入库两条重复数据的情况; 但是我查看代码, 页面做了校验, 后台插入数据也做了校验;  出现这种几率的事件的非常小的, 但是还是会碰到, 客户会对我们的产品产 ...

  2. java关键字总结

    static: 用来修饰成员变量和成员方法,也可以形成静态static代码块,可以形成静态内部类,也可以用于静态导包. 1.静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实 ...

  3. windows 下的命令操作

    删除文件夹 RD /S D:\aaaaa 删除文件夹下的文件 DEL D:\aaaaa\*.*

  4. weex npm 报错 cb() never called!

    安装环境:windows7 使用npm 安装 出现错误后网上查找并没有解决,在准备放弃的时候试着用cnpm安装了一下,结果安装成功了,感觉应该网络问题,不知原因但完美解决

  5. killl prefix out macro mis mal micro -m

    1● macro 宏大,规模大   2● mis 错误,坏   3● mal 坏,错误   4● micro 小,微小  

  6. 外部调用mvc的api方法时,如何解决跨域请求问题?

    首先,创建一个mvc项目(包含webapi),我们模拟一个场景 1)在项目的Controller 创建一个WeiXinApiController public class WeiXinApiContr ...

  7. Mysql索引引起的死锁

    提到索引,首先想到的是效率提高,查询速度提升,不知不觉都会有一种心理趋向,管它三七二十一,先上个索引提高一下效率..但是索引其实也是暗藏杀机的... 今天压测带优化项目,开着Jmeter高并发访问项目 ...

  8. linux下查看运行进程详细信息

    通过ps及top命令查看进程信息时,只能查到相对路径,查不到的进程的详细信息,如绝对路径等.这时,我们需要通过以下的方法来查看进程的详细信息: Linux在启动一个进程时,系统会在/proc下创建一个 ...

  9. Weka里如何将arff文件或csv文件批量导入MySQL数据库(六)

    这里不多说,直接上干货! 前提博客是 Weka中数据挖掘与机器学习系列之数据格式ARFF和CSV文件格式之间的转换(四) 1.将arff文件批量导入MySQL数据库 我在这里,arff文件以Weka安 ...

  10. VS Code 常用快捷键

    VS Code 常用快捷键 1.注释: 单行注释:ctrl+/, 注释后再按取消 取消单行注释:alt+shift+A 注释后再按取消 2.移动行 向上移动一行:alt+up 向下移动一行:alt+d ...