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

发布于 2024-11-19 03:31:52 字数 1396 浏览 2 评论 0原文

此代码适用于使用阻塞套接字的 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_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

This code is for an HTTPS server using blocking sockets:

  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() always returns zero and the SSL_read() is never reached. If the SSL_pending() call is removed, SSL_read() is executed. Why doesn't SSL_pending() indicate how many bytes are available?

Note that if you call SSL_read() and the number of bytes returned is less than your buffer size, you've read everything and are done.

If the incoming data is larger than your buffer size, the first SSL_read() call fills the buffer, and you can repeat calling SSL_read() until you can't fill the buffer.

BUT if the incoming data is an exact multiple of your buffer size, the last chunk of data fills the buffer. If you attempt another SSL_read() thinking there might be more data on a blocking socket, it hangs indefinitely. Hence the desire to check SSL_pending() first. Yet that doesn't appear to work.

How do you avoid hanging on a final SSL_read()? (I can't imagine the answer is to go non-blocking, since that means you could never use SSL_read with blocking.)

UPDATE: The following works. Apparently SSL_pending() doesn't work until after the first 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白芷 2024-11-26 03:31:52

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

You are using SSL_pending() the completely wrong way. OpenSSL uses a state machine, where SSL_pending() indicates if the state machine has any pending bytes that have been buffered and are awaiting processing. Since you are never calling SSL_read(), you are never buffering any data or advancing the state machine.

彡翼 2024-11-26 03:31:52

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

If the SSL_pending function returns a return code of 0, it does not necessarily mean that there is no data immediately available for reading on the SSL session. A return code of 0 indicates that there is no more data in the current SSL data record. However, more SSL data records may have been received from the network already. If the SSL_pending function returns a return code of 0, issue the select function, passing the file descriptor of the socket to check if the socket is readable. Readable means more data has been received from the network on the socket.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文