ssl_write直接程序挂掉

本文介绍了一个关于socket切换到openssl后出现的问题:客户端主动断开连接导致服务器崩溃。通过忽略SIGPIPE信号解决了该问题。

socket改为openssl之后,发现client主动关闭后,heartbeat发数据引起server端直接挂死,无任何coredump文件。

百度谷歌无解,突然想到了broken pipe问题,测试后发现果然是此问题,在main函数中添加signal(SIGPIPE, SIG_IGN)忽略此信号即可。

### SSL_write 函数的使用方法 `SSL_write` 是 OpenSSL 提供的一个函数,用于在 SSL/TLS 连接上发送加密数据。其基本原型如下: ```c int SSL_write(SSL *ssl, const void *buf, int num); ``` - **参数说明**: - `ssl`:指向已建立 SSL 连接的 SSL 对象。 - `buf`:待发送的数据缓冲区。 - `num`:要发送的数据长度(字节数)。 该函数返回值为实际发送的字节数,若返回负值则表示发生错误 [^3]。 在调用 `SSL_write` 时,需要确保 SSL 握手已经完成。通常情况下,在 TCP 连接建立后,需先调用 `SSL_connect`(客户端)或 `SSL_accept`(服务端)完成握手过程,之后才能进行数据传输 [^1]。 ### 常见错误 1. **SSL_ERROR_WANT_READ / SSL_ERROR_WANT_WRITE** 在调用 `SSL_write` 时,如果底层 I/O 操作未准备好(例如套接字不可写),OpenSSL 会返回 `SSL_ERROR_WANT_WRITE` 错误码。此时应将当前连接注册到事件循环(如 epoll)中,并在其变为可写状态时继续调用 `SSL_write` [^1]。 2. **SSL_ERROR_SYSCALL** 表示底层系统调用(如 `write` 或 `send`)发生了错误。常见原因包括连接中断、文件描述符无效等。可以通过检查 `errno` 获取更详细的错误信息 [^3]。 3. **SSL_ERROR_SSL** 表示在 SSL 协议层发生了错误,可能由证书验证失败、协议版本不匹配等原因引起。可通过 `ERR_get_error()` 获取具体的错误代码 [^2]。 4. **证书验证失败** 如果服务器配置了客户端证书认证或使用了自签名证书,可能导致 `SSL_write` 调用失败,并伴随类似 `upstream SSL certificate verify error` 的日志信息 [^2]。 ### 性能问题 1. **频繁的小数据块写入** `SSL_write` 每次调用都会触发一次 TLS 记录层的加密和封装操作。如果频繁发送小数据包,会导致性能下降。建议采用批量发送策略或将多个小数据合并后再调用 `SSL_write`。 2. **非阻塞模式下的重试机制** 在非阻塞模式下,由于 `SSL_write` 可能返回 `SSL_ERROR_WANT_WRITE`,应用程序需要等待事件通知再继续发送。这种机制虽然可以避免线程阻塞,但也增加了事件处理的复杂性和延迟。 3. **加密开销** 加密操作本身会带来一定的 CPU 开销,尤其是在高并发场景下。可以通过启用硬件加速(如 Intel QuickAssist 技术)或选择轻量级加密算法(如 AES-GCM)来优化性能。 4. **Nagle 算法与延迟问题** 默认情况下,TCP 使用 Nagle 算法来减少小数据包的数量,但这可能会引入额外的延迟。对于低延迟要求的应用,可以通过设置 `TCP_NODELAY` 来禁用 Nagle 算法,从而提升响应速度。 ### 示例代码 以下是一个简单的 `SSL_write` 使用示例: ```c #include <openssl/ssl.h> #include <openssl/err.h> void send_data(SSL *ssl) { const char *msg = "Hello, secure world!"; int len = strlen(msg); int sent = SSL_write(ssl, msg, len); if (sent <= 0) { int err = SSL_get_error(ssl, sent); if (err == SSL_ERROR_WANT_WRITE) { // 注册可写事件并等待 } else { ERR_print_errors_fp(stderr); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值