Https 为什么这个SSL_挂起调用总是返回零?

Https 为什么这个SSL_挂起调用总是返回零?,https,openssl,winsock,Https,Openssl,Winsock,此代码适用于使用阻止套接字的HTTPS服务器: request := ''; start := gettickcount; repeat if SSL_pending(ssl) > 0 then begin bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1); if bytesin > 0 then begin buffer[bytesin] :=

此代码适用于使用阻止套接字的HTTPS服务器:

  request := '';
  start := gettickcount;
  repeat
    if SSL_pending(ssl) > 0 then
      begin
      bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1);
      if bytesin > 0 then
        begin
        buffer[bytesin] := #0;
        request := request + buffer;
        end
      else break; // read failed
      end; // pending
   until (gettickcount - start) > LARGETIMEOUT;
   // "request" is ready, though possibly empty
SSL_pending始终返回零,并且永远不会达到SSL_读取。如果删除SSL_挂起调用,则执行SSL_读取。为什么SSL_pending不指示有多少字节可用

请注意,如果调用SSL_read并且返回的字节数小于缓冲区大小,那么您已经读取了所有内容并完成了读取

如果传入数据大于缓冲区大小,则第一个SSL_读取调用将填充缓冲区,您可以重复调用SSL_读取,直到无法填充缓冲区为止

但是,如果传入数据是缓冲区大小的精确倍数,则最后一块数据将填充缓冲区。如果您尝试另一次SSL_读取,认为阻塞套接字上可能有更多数据,那么它将无限期挂起。因此,希望首先检查SSL_挂起。但这似乎不起作用

如何避免挂在最后的SSL_读取上?我无法想象答案是非阻塞,因为这意味着您永远无法将SSL_read与阻塞一起使用

更新:以下工作。显然,SSL_挂起直到第一次读取SSL_之后才起作用:

  request := '';
  repeat
    bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1);
    if bytesin > 0 then
      begin
      buffer[bytesin] := #0;
      request := request + buffer;
      end
    else break; // read failed
  until SSL_pending(ssl) <= 0;
  // "request" is ready, though possibly empty

您正在以完全错误的方式使用SSL_。OpenSSL使用状态机,其中SSL_pending指示状态机是否有任何已缓冲且正在等待处理的挂起字节。由于您从未调用SSL_read,因此您从未缓冲任何数据或推进状态机。

如果SSL_pending函数返回的返回码为0,则不一定意味着SSL会话上没有可立即读取的数据。返回代码0表示当前SSL数据记录中没有更多数据。但是,可能已经从网络接收到更多SSL数据记录。如果SSL_pending函数返回的返回码为0,则发出select函数,传递套接字的文件描述符以检查套接字是否可读。可读意味着在套接字上从网络接收到更多数据。

SSL\u pending sure的文档没有明确说明这一点。它有点明确:获取SSL对象中缓冲的可读字节数……数据可以在SSL中缓冲,并可以使用SSL\u read3立即检索