为什么这个SSL_pending调用总是返回零?

Wit*_*292 7 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] := #0;
        request := request + buffer;
        end
      else break; // read failed
      end; // pending
   until (gettickcount - start) > LARGETIMEOUT;
   // "request" is ready, though possibly empty
Run Code Online (Sandbox Code Playgroud)

SSL_pending()始终返回零,并且永远不会到达SSL_read().如果删除了SSL_pending()调用,则执行SSL_read().为什么SSL_pending()不指示可用的字节数?

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

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

但是如果传入的数据是缓冲区大小的精确倍数,则最后一块数据填充缓冲区.如果您尝试另一个SSL_read()认为阻塞套接字上可能有更多数据,它会无限期挂起.因此,首先要检查SSL_pending().然而,这似乎不起作用.

你如何避免挂在最后的SSL_read()上?(我无法想象答案是非阻塞,因为这意味着你永远不能将SSL_read与阻塞一起使用.)

更新: 以下工作.显然SSL_pending()在第一个SSL_read()之后才起作用:

  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
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 6

你使用的SSL_pending()是完全错误的方式.OpenSSL使用状态机,其中SSL_pending()指示状态机是否具有已缓冲且正在等待处理的任何待处理字节.由于您从不打电话SSL_read(),因此您永远不会缓冲任何数据或推进状态机.

  • SSL_pending的文档肯定没有说清楚. (8认同)