.阻塞模型,select读有数据,ssl_read读取数据返回-1优化代码
时间: 2024-02-20 13:02:00 浏览: 80
针对这种情况,你可以尝试以下优化代码:
1. 在调用ssl_read之前,先检查SSL握手状态,确保握手已经成功完成,否则重新进行握手。
2. 在调用ssl_read之前,先检查SSL会话是否过期,如果过期,可以考虑重新建立SSL会话。
3. 在调用ssl_read之前,先检查网络连接状态,如果连接已经中断,可以考虑进行重连或者其他网络故障处理操作。
4. 在调用ssl_read之前,使用非阻塞模式进行设置,可以避免阻塞。如果ssl_read返回-1并且errno为EAGAIN或EWOULDBLOCK,则可以再次调用select等待数据可读,直到ssl_read返回正确的数据或者出现其他错误。
5. 在代码中加入错误处理代码,避免出现逻辑错误。同时,可以加入日志记录功能,便于排查问题。
示例代码:
```
// 设置非阻塞模式
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
// SSL握手
if (SSL_do_handshake(ssl) != 1) {
int err = SSL_get_error(ssl, ret);
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
// 握手未完成,等待下一次循环
continue;
} else {
// 握手失败,关闭连接
close(fd);
return -1;
}
}
// 检查SSL会话是否过期
if (SSL_session_reused(ssl) == 0) {
// SSL会话过期,重新建立SSL会话
SSL_set_session(ssl, NULL);
SSL_set_fd(ssl, fd);
if (SSL_connect(ssl) != 1) {
close(fd);
return -1;
}
}
// 检查网络连接状态
if (select(fd + 1, &readfds, NULL, NULL, &tv) <= 0) {
// 连接中断,重连或其他处理
close(fd);
return -1;
}
// 读取数据
int nread = 0;
while ((nread = SSL_read(ssl, buf, len)) <= 0) {
int err = SSL_get_error(ssl, nread);
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
// 数据未准备好,等待下一次循环
continue;
} else {
// 其他错误,退出循环
break;
}
}
```
阅读全文