【发布时间】:2015-02-27 00:28:19
【问题描述】:
这里
http://marc.info/?l=openssl-users&m=124386218929227
说明
"...这就是为什么理解任何端口上的任何可能的转发进度(以及返回 WANT_READ 的写入操作可能已经取得转发进度!)要求您重试所有端口上的所有挂起操作非常重要的原因。 ……”
那么我是否正确理解返回 WANT_READ 的 SSL_read() 可能已经取得了进展(即使它没有返回任何数据)?
我有一个事件驱动的单线程应用程序,它有 3 个非阻塞 ssl 套接字。当每个套接字完成其连接时,我会读取这些套接字,直到获得WANT_READ。我的理解是WANT_READ 意味着我现在可以调用select() 并等待套接字准备好再次读取。
当select() 返回时,一个循环会遍历三个套接字,分别调用ssl_read()。
说对 Socket 1 的读取返回了 WANT_READ 并且没有数据。
套接字 2 是否有可能返回一些数据,当没有更多要读取的内容时返回 WANT_READ,并且现在已经取得了一些进展,因此套接字 1 上的读取现在可以返回数据?但是由于循环已经完成了对套接字 1 的读取,所以它不会发生。
由于循环已通过 3 个套接字,它在那里等待并挂起。这种情况会发生吗?
如果是这种情况,我如何查看是否在所有 3 个插槽上都无法取得更多进展? 例如,假设循环贯穿;
- socket 1 返回
WANT_READ。 - socket 2 返回一些数据,然后
WANT_READ(并取得进展,socket 1 现在可以返回数据) - socket 3 返回
WANT_READ。
但是根据上面的引用(任何向前的进展都需要重试所有挂起的操作),我应该再次重试所有套接字;所以第二次运行循环;
- socket 1 现在返回数据,然后
WANT_READ - socket 2 返回
WANT_READ - socket 3 现在返回数据(因为 socket 1 上的读取取得了足够的进展,socket 3 返回数据),然后
WANT_READ。
但是如果套接字 3 上的最后一次读取取得了进展,那么套接字 2 现在再次返回数据怎么办?所以我的问题是(如果我的理解是正确的),我如何判断是否无法取得更多进展?
编辑 1:
所以我看到的是这样的:
我的循环遍历连接到 client1 的所有套接字(例如,有 2 个套接字)
- socket 1:
ssl_read()返回 WANT_READ - socket 2:
ssl_read()返回数据,ssl_read()再次返回数据,然后ssl_read()最终返回WANT_READ
然后,由于所有套接字都返回 WANT_READ,我等待select()。但是,我的应用仍在等待客户端已经发送的数据。如果我让客户端启动另一个连接(同时保持原件处于活动状态),则选择返回,这就是我所看到的:
- socket 1:
ssl_read()返回数据,然后ssl_read()再次返回 WANT_READ - socket 2:
ssl_read()返回 WANT_READ - socket 3(新):
ssl_read()返回数据,然后返回 WANT_READ。
所以 select 检测到新连接并运行我的循环,该循环遍历所有活动连接。这一次,除了套接字 3 上的新数据之外,它还从上次的套接字 1 中找到数据。所以我的理论是 select() 不会第一次返回,因为我在套接字上等待接收的数据1 已经到了,准备好等待我调用 ssl_read()。但上次我调用 ssl_read 时,我得到了 WANT_READ。
【问题讨论】:
标签: openssl nonblocking