如何使 SSL 读取阻塞?

Posted

技术标签:

【中文标题】如何使 SSL 读取阻塞?【英文标题】:How to make SSL reads block? 【发布时间】:2021-07-19 08:11:18 【问题描述】:

我正在尝试使 SSL_read() block 直到从服务器接收到数据。我尝试在我的“连接”代码中将套接字设置为阻塞

  
    u_long iMode = 1;
    i = ioctlsocket(sock, FIONBIO, &iMode);
  

但奇怪的是,我每次都会遇到堆栈溢出异常。还有其他更正确的方法吗? (注意:如果我省略此代码,应用程序就可以正常工作)。 我已经在这个问题上搜索了 SO,但在任何地方人们似乎都遇到了相反的问题,即在他们想要非阻塞时阻塞。

代码概要:

Get method: TLS_client_method()
Get CTX: SSL_CTX_new(method)
Create socket 'sock'
set socket to blocking (code above)
Connect sock to host on port 443
Create SSL*: ssl=SSL_new(ctx)
SSL_set_fd(ssl, sock)  
Do SSL_reads and writes

【问题讨论】:

它默认阻止。您已将其设置为 阻塞模式。阅读文档。或者注意标志:NBIO:非阻塞 I/O。 【参考方案1】:

通过从 SSL_* 调用切换到 BIO_* 调用以进行连接、读取、写入等,我实现了我想要的。

BIO 系列包括设置阻塞/非阻塞模式的函数“BIO_set_nbio()”。效果很好。

示例代码概要(例如,用于 google.com):

Get method: method = TLS_client_method()
Get CTX: ctx = SSL_CTX_new(method)
Create BIO object: bio = BIO_new_ssl_connect( ctx )
Create socket 'sock'
Connect 'sock' to google.com, port 443
Create SSL*: ssl = SSL_new(ctx)
SSL_set_mode( ssl, SSL_MODE_AUTO_RETRY )
BIO_set_conn_hostname( bio, "google.com:443" )
BIO_do_connect( bio )
BIO_set_nbio( bio, mode ) (with mode=0 for blocking)
Now can do blocking BIO_reads and writes (with BIO_read, BIO_write)

【讨论】:

您通过省略问题中的代码实现了您所说的想要的。您在这里所做的只是完全失去 SSL。 我将新代码添加到我的答案中。我不知道您所说的“丢失” SSL 是什么意思。

以上是关于如何使 SSL 读取阻塞?的主要内容,如果未能解决你的问题,请参考以下文章

非阻塞套接字仍然可以在 OpenSSL 中阻塞吗?

在 Python 中对 subprocess.PIPE 进行非阻塞读取

在 Python 中对 subprocess.PIPE 进行非阻塞读取

在 Python 中对 subprocess.PIPE 进行非阻塞读取

在 Python 中对 subprocess.PIPE 进行非阻塞读取

如何使 UdpClient 非阻塞