使用OpenSSL TLS时如何读取超过16384字节的数据
问题原因
TLS协议记录层默认单条记录的明文最大长度为16384字节,OpenSSL的SSL_read单次调用只会返回单条TLS记录的内容,所以不管传入的缓冲区多大,单次调用最多返回16384字节属于正常设计,并非功能异常。你当前代码仅调用一次SSL_read,自然只能拿到最多16KB的数据。
解决方法
循环调用SSL_read直到读取完所有目标数据,同时处理返回值的不同分支,另外你原有代码还存在缓冲区过大、未按实际读取长度追加内容、字符串初始化错误等问题,修正后的代码如下:
#include <openssl/ssl.h> #include <string> #include <vector> // 假设InitCTX、OpenConnection为你已实现的函数 SSL_CTX* InitCTX(); int OpenConnection(); int main() { SSL_CTX* ctx; int server; SSL* ssl; int bytes; std::string result; // 不需要申请超大缓冲区,16KB即可满足单次读取上限 std::vector<char> buffer(16384); ctx = InitCTX(); server = OpenConnection(); ssl = SSL_new(ctx); SSL_set_fd(ssl, server); if (SSL_connect(ssl) != -1) { // 原有写法std::string msg = 0属于非法操作,会触发空指针访问崩溃 std::string msg = "你的实际请求内容"; SSL_write(ssl, msg.c_str(), msg.size()); while (true) { bytes = SSL_read(ssl, buffer.data(), buffer.size()); if (bytes > 0) { // 仅追加实际读取到的字节,避免写入无效数据 result.append(buffer.data(), bytes); } else { int ssl_err = SSL_get_error(ssl, bytes); if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) { // 非阻塞模式下等待套接字就绪后重试即可,阻塞模式不会返回该错误 continue; } else if (ssl_err == SSL_ERROR_ZERO_RETURN) { // 对端正常关闭TLS连接,读取结束 break; } else { // 发生传输错误,可在此处添加错误处理逻辑 break; } } } } // 记得释放资源,避免内存泄漏 SSL_free(ssl); close(server); SSL_CTX_free(ctx); return 0; }
额外说明
如果你的业务场景可以提前预知要读取的总数据长度(比如HTTP协议响应头里的Content-Length字段),可以在循环中追加读取长度判断,达到目标长度后直接终止循环,不需要等待对端关闭连接。
内容的提问来源于stack exchange,提问作者qwerty123456
相关产品推荐
相关产品推荐

