这是我的问题: 在调用accept或connect之前将套接字设置为非阻塞是否不好?或者应该使用阻塞接受和连接,然后将套接字更改为非阻塞?
我是 OpenSSL 新手,对网络编程经验不是很丰富。我的问题是我尝试使用 OpenSSL 和非阻塞套接字网络来增加安全性。当我在服务器端调用 SSL_accept 并在客户端调用 SSL_connect 时,并使用
检查返回错误代码SSL_get_error(m_ssl, n);
char error[65535];
ERR_error_string_n(ERR_get_error(), error, 65535);
SSL_get_error 的返回码表示 SSL_ERROR_WANT_READ,而 ERR_error_string_n 打印出“error:00000000:lib(0):func(0):reason(0)”,我认为这意味着没有错误。 SSL_ERROR_WANT_READ 意味着我需要重试 SSL_accept 和 SSL_connect。
然后我使用循环来重试这些函数,但这只会导致无限循环:(
我相信我已经正确初始化了 SSL,这是代码
//CRYPTO_malloc_init();
SSL_library_init();
const SSL_METHOD *method;
// load & register all cryptos, etc.
OpenSSL_add_all_algorithms();
// load all error messages
SSL_load_error_strings();
if (server) {
// create new server-method instance
method = SSLv23_server_method();
}
else {
// create new client-method instance
method = SSLv23_client_method();
}
// create new context from method
m_ctx = SSL_CTX_new(method);
if (m_ctx == NULL) {
throwError(-1);
}
如果有任何我没有提到的部分,但您认为这可能是问题,请告诉我。
SSL_ERROR_WANT_READ 意味着我需要重试 SSL_accept 和 SSL_connect。
是的,但这不是故事的全部。 您应该仅在套接字可读后重试调用,例如您需要使用
select
或 poll
或类似的函数来等待,直到套接字变得可读。同样适用于 SSL_ERROR_WANT_WRITE,但这里你必须等待套接字变得可写。
如果你不等待就重试,它可能最终会成功,但前提是在有数百次失败的调用之后。虽然这样做
select
并不能保证它会在下一次调用时立即成功,但它只需要几次 SSL_connect/SSL_accept 调用就可以成功,并且同时不会忙于循环并占用 CPU。