Openssl 如何判断何时无法在SSL连接上取得更多进展

Openssl 如何判断何时无法在SSL连接上取得更多进展,openssl,nonblocking,Openssl,Nonblocking,这里 它说 “…这就是为什么了解任何端口上的任何可能的正向进程(以及返回WANT_READ的写入操作可能已经取得正向进程!)都要求您在所有端口上重试所有挂起的操作非常重要…” 因此,我是否正确地理解了返回WANT\u read的SSL\u read()可能已经取得了进展(即使它没有返回任何数据) 我有一个事件驱动的单线程应用程序,它有3个非阻塞ssl套接字。当每个套接字完成连接时,我会一直读取套接字,直到得到一个WANT\u read。我的理解是,WANT\u READ意味着我现在可以调用se

这里

它说

“…这就是为什么了解任何端口上的任何可能的正向进程(以及返回WANT_READ的写入操作可能已经取得正向进程!)都要求您在所有端口上重试所有挂起的操作非常重要…”

因此,我是否正确地理解了返回
WANT\u read
SSL\u read()
可能已经取得了进展(即使它没有返回任何数据)

我有一个事件驱动的单线程应用程序,它有3个非阻塞ssl套接字。当每个套接字完成连接时,我会一直读取套接字,直到得到一个
WANT\u read
。我的理解是,
WANT\u READ
意味着我现在可以调用
select()
并等待套接字准备好再次读取

select()
返回时,一个循环通过3个套接字,分别调用
ssl\u read()

假设套接字1上的读取返回了
想要读取
但没有数据。 是否有可能套接字2返回一些数据,当没有更多的数据可读取时返回
想要读取
,并且现在已经取得了一些进展,因此套接字1上的读取现在可以返回数据?但是由于循环已经完成了套接字1的读取,所以不会发生这种情况

由于循环已通过3个套接字,因此它在那里等待并挂起。这种情况会发生吗

如果是这种情况,我如何判断是否在所有3个插座上都无法取得更多进展? 例如,假设循环穿过

  • 套接字1返回
    WANT\u READ
  • 套接字2返回一些数据,然后
    WANT\u READ
    (并取得进展,使套接字1现在可以返回数据)
  • 套接字3返回
    WANT\u READ
但是根据上面的引用(任何向前的进程都需要重试所有挂起的操作),我应该再次重试所有套接字;因此,第二次运行通过循环

  • 套接字1现在返回数据,然后
    WANT\u READ
  • 套接字2返回
    WANT\u READ
  • 套接字3现在返回数据(因为套接字1上的读取进度足以让套接字3返回数据),然后
    WANT\u read
但是,如果套接字3上的最后一次读取取得了进展,那么套接字2现在会再次返回数据吗?所以我的问题是(如果我的理解是正确的),我如何判断是否不能取得更多的进展

编辑1:

所以我看到的是:

我的循环通过连接到client1的所有套接字(例如有2个套接字)运行

  • 套接字1:
    ssl\u read()
    返回所需读取
  • 套接字2:
    ssl\u read()
    返回数据,
    ssl\u read()
    再次返回数据,然后
    ssl\u read()
    最终返回想要读取的数据
然后,由于所有套接字都返回了WANT\u READ,我等待
select()
。但是,我的应用程序仍在等待客户端已发送的数据。如果我让客户端启动另一个连接(同时保持原始连接处于活动状态),请选择returns,这就是我看到的:

  • 套接字1:
    ssl\u read()
    返回数据,然后
    ssl\u read()
    再次返回想要读取的数据
  • 套接字2:
    ssl\u read()
    返回所需读取
  • 套接字3(新):
    ssl\u read()
    返回数据,然后返回WANT\u read
因此,select检测新连接并通过我的循环运行,该循环通过所有活动连接。这一次,除了套接字3上的新数据外,它还找到了上次套接字1中的数据。所以我的理论是select()不会第一次返回,因为我在套接字1上等待接收的数据已经到达,并且已经准备好,等待我调用ssl_read()。但是上次我调用ssl\u read时,我得到了WANT\u read。

ssl\u read()
返回负值时,您应该从
ssl\u get\u error()
获取错误代码。如果错误代码为SSL\u error\u WANT\u READ,则意味着您应该等待(例如,使用
select()
poll
)使该套接字可读(直到一些数据从网络到达)。发生这种情况时,您应该再次在该套接字上重试SSL_read()您不必在您拥有的所有SSL套接字上重试
SSL\u read()
,只需在返回SSL\u ERROR\u WANT\u read的套接字上重试即可。您应该使用
SSL\u write()
(当它返回
SSL\u ERROR\u WANT\u write
时)执行类似的操作

但是要小心,
SSL\u read()
可能会返回(
SSL\u get\u error()
也就是说)
SSL\u error\u WANT\u WRITE
SSL\u WRITE()
可能会返回
SSL\u error\u WANT\u read
。这可能会发生,因为SSL需要发送/接收数据之外的一些附加消息(例如,为了发送数据,它需要先发送一些消息并接收响应)

总结如下:

  • n=SSL\u read()
    返回:

    a)
    n>0
    -->您刚刚收到
    n
    字节的数据

    b)
    n<0
    -->
    err=SSL\u get\u error()
    返回

    • SSL\u错误\u想要读取-->
      select()
      直到套接字可读,然后再次调用
      SSL\u读取()
    • SSL\u错误\u想要写入-->
      select()
      直到套接字可写,然后再次调用
      SSL\u read()
    c)
    n=0
    -->
    if(SSL\u get\u shutdown(SSL*)和SSL\u RECEIVED\u shutdown)
    :另一端确实清除了关机,否则关机不干净,但SSL连接已关闭。您也可以关闭套接字(SSL*对象)

  • n=SSL\u write()
    返回:

    a)
    n>0
    -->您刚刚发送了
    n
    字节的数据

    b)
    n<0
    -->
    err=SSL\u get\u error()
    返回

    • SSL\u错误\u希望\u读取-->
      select()
      直到套接字可读并调用