这里
http://marc.info/?l=openssl-users&m=124386218929227
它指出
“...这就是为什么理解任何端口上任何可能的转发进度(以及返回 WANT_READ 的写入操作可能已经取得转发进度!)要求您重试所有端口上的所有挂起操作非常重要的原因...... "
那么我是否正确理解SSL_read()
返回的WANT_READ
可能已经取得了进展(即使它没有返回任何数据)?
我有一个事件驱动的单线程应用程序,它有 3 个非阻塞 ssl 套接字。当每个套接字完成其连接时,我会读取套接字,直到我得到一个WANT_READ
. 我的理解是,WANT_READ
我现在可以调用select()
并等待套接字准备好再次读取的一种方法。
返回时select()
,循环通过 3 个套接字调用ssl_read()
它们中的每一个。
说对 Socket 1 的读取返回WANT_READ
并且没有数据。套接字 2 是否有可能返回一些数据,WANT_READ
在没有更多内容可读取时返回,并且现在已经取得了一些进展,因此套接字 1 上的读取现在可以返回数据?但是由于循环已经完成了对套接字 1 的读取,所以它不会发生。
由于循环已通过 3 个套接字,它在那里等待并挂起。这种情况会发生吗?
如果是这种情况,我如何查看是否在所有 3 个插槽上都无法取得更多进展?例如,假设循环贯穿;
- 套接字 1 返回
WANT_READ
。 - 然后套接字 2 返回一些数据
WANT_READ
(并取得进展,使套接字 1 现在可以返回数据) - 套接字 3 返回
WANT_READ
。
但是根据上面的引用(任何向前的进展都需要重试所有挂起的操作),我应该再次重试所有套接字;所以第二次通过循环;
- socket 1 现在返回数据,然后
WANT_READ
- 套接字 2 返回
WANT_READ
- 套接字 3 现在返回数据(因为套接字 1 上的读取取得了足够的进展,使套接字 3 返回数据),然后
WANT_READ
.
但是,如果套接字 3 上的最后一次读取取得了进展,那么套接字 2 现在再次返回数据怎么办?所以我的问题是(如果我的理解是正确的),我怎么知道是否无法取得更多进展?
编辑1:
所以我看到的是这样的:
我的循环贯穿连接到 client1 的所有套接字(例如,有 2 个套接字)
- 套接字 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 - 套接字 2:
ssl_read()
返回 WANT_READ - socket 3(new):
ssl_read()
返回数据,然后返回 WANT_READ。
因此 select 检测到新连接并运行我的循环,该循环遍历所有活动连接。这一次,除了套接字 3 上的新数据之外,它还从上次的套接字 1 中找到数据。所以我的理论是 select() 不会第一次返回,因为我在套接字上等待接收的数据1 已经到了,准备好等待我调用 ssl_read()。但上次我调用 ssl_read 时,我得到了 WANT_READ。