You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用mbedtls库时,如何结合select()检测SSL上下文缓存数据?

解决mbedtls结合select()时的缓存数据读取问题

要解决这个问题,核心是先检查mbedtls SSL上下文的内部缓存,再用select()监听底层套接字——因为SSL层会提前将底层套接字的数据读取并缓存,此时底层fd无数据但SSL上下文有未读内容,select()不会触发。

关键思路

  1. 每次尝试读取前,先调用mbedtls_ssl_get_bytes_avail()检查SSL上下文缓存中是否有未读字节:
    • 返回值>0:直接调用mbedtls_ssl_read()读取缓存数据,无需等待select()
    • 返回值=0:再用select()监听底层套接字的可读事件
  2. 处理mbedtls_ssl_read()返回的MBEDTLS_ERR_SSL_WANT_READ/MBEDTLS_ERR_SSL_WANT_WRITE错误:
    • 这类错误表示当前SSL操作需要等待底层套接字的可读/可写事件,需重新进入select()等待

示例代码

#include <mbedtls/ssl.h>
#include <mbedtls/net.h>
#include <sys/select.h>

int ssl_select_and_read(mbedtls_ssl_context *ssl, mbedtls_net_context *net, void *buf, size_t len) {
    int ret;
    fd_set read_fds, write_fds;
    struct timeval tv;

    // 先检查SSL上下文缓存是否有未读数据
    size_t avail = mbedtls_ssl_get_bytes_avail(ssl);
    if (avail > 0) {
        return mbedtls_ssl_read(ssl, buf, len);
    }

    // 缓存无数据,用select等待底层套接字可读
    FD_ZERO(&read_fds);
    FD_SET(net->fd, &read_fds);

    tv.tv_sec = 5; // 自定义超时时间
    tv.tv_usec = 0;

    ret = select(net->fd + 1, &read_fds, NULL, NULL, &tv);
    if (ret < 0) {
        // select错误处理
        return ret;
    } else if (ret == 0) {
        // 超时处理
        return -1;
    }

    // 套接字可读,调用ssl_read
    ret = mbedtls_ssl_read(ssl, buf, len);
    while (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
        if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
            FD_ZERO(&read_fds);
            FD_SET(net->fd, &read_fds);
            ret = select(net->fd + 1, &read_fds, NULL, NULL, &tv);
        } else { // MBEDTLS_ERR_SSL_WANT_WRITE
            FD_ZERO(&write_fds);
            FD_SET(net->fd, &write_fds);
            ret = select(net->fd + 1, NULL, &write_fds, NULL, &tv);
        }

        if (ret <= 0) {
            return ret;
        }

        ret = mbedtls_ssl_read(ssl, buf, len);
    }

    return ret;
}

注意事项

  • mbedtls_ssl_get_bytes_avail()仅能获取SSL应用层缓存的未读数据,不包括正在处理的SSL记录
  • 处理MBEDTLS_ERR_SSL_WANT_WRITE时,需要监听套接字的可写事件,因为SSL握手或加密操作可能需要写入数据
  • 实际使用中需根据业务需求调整超时时间和错误处理逻辑

内容的提问来源于stack exchange,提问作者n3mo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 19:44:57