SSL_read因SSL_ERROR_WANT_READ阻塞后必须要等SSL_read完成才可以继续调用SSL_write吗?
我现在项目需要将SSL阻塞方式改为非阻塞方式,使用的多线程,在一个线程中对一个SSL对象SSL_write,在另一个线程中使用该对象进行SSL_read操作。
在《Network Security with OpenSSL》讲non-blocking的一节中有个data_transfer的示例程序:
for (;;)
{
/* check_availability使用I/O复用接口(select、poll、epoll等)来获取socket是否可读或可写 */
check_availability(A, &can_read_A, &can_write_A, B, &can_read_B, &can_write_B);
/* write_waiton_read_A:调用SSL_write时因SSL_ERROR_WANT_READ阻塞
* write_waiton_write_A:调用SSL_write时因SSL_ERROR_WANT_WRITE阻塞
* read_waiton_write_A:调用SSL_read时因SSL_ERROR_WANT_WRITE阻塞
* read_waiton_read_A:调用SSL_read时因SSL_ERROR_WANT_READ阻塞
*/
if (!(write_waiton_read_A || write_waiton_write_A) && // A的write没有完成
(A2B_len != BUF_SIZE) &&
/* A可读,或者之前read因WANT_WRITE阻塞而此时A可写 */
(can_read_A || (can_write_A && read_waiton_write_A)))
{
read_waiton_read_A = 0;
read_waiton_write_A = 0;
code = SSL_read(A, A2B + A2B_len, BUF_SIZE - A2B_len);
switch (SSL_get_error(A, code))
{
...
case SSL_ERROR_WANT_READ:
read_waiton_read_A = 1;
break;
case SSL_ERROR_WANT_WRITE:
read_waiton_write_A = 1;
break;
...
}
}
...
if (!(read_waiton_write_A || read_waiton_read_A) &&
have_data_B2A &&
/* A可写,或者write因WANT_READ阻塞而此时A可读 */
(can_write_A || (can_read_A && write_waiton_read_A)))
{
write_waiton_read_A = 0;
write_waiton_write_A = 0;
code = SSL_write(A, B2A, B2A_len);
switch (SSL_get_error(A, code))
{
...
case SSL_ERROR_WANT_READ:
write_waiton_read_A = 1;
break;
case SSL_ERROR_WANT_WRITE:
write_waiton_write_A = 1;
...
}
}
...
}
上面的代码中,如果A之前的SSL_read因SSL_ERROR_WANT_READ未完成,则需等SSL_read完成才能对A进行SSL_write(就算A此时可写)。
我程序中的连接在发送时同时需要接收,请问如果一个SSL对象的操作(比如SSL_read)阻塞(比如因SSL_ERROR_WANT_READ)后,必须等该操作完成后才能调用另外一个对应的操作(比如SSL_write)吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
应该是的,由于重协商的存在,SSL_write也会产生SSL_ERROR_WANT_READ。如果你不处理完SSL_read,后面发生可读事件时,怎么知道要调用SSL_write还是SSL_read?