为什么这个 SSL_pending 调用总是返回零?
此代码适用于使用阻塞套接字的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您使用
SSL_pending()
的方式完全错误。 OpenSSL 使用状态机,其中SSL_pending()
指示状态机是否有任何已缓冲并正在等待处理的待处理字节。由于您从未调用SSL_read()
,因此您永远不会缓冲任何数据或推进状态机。You are using
SSL_pending()
the completely wrong way. OpenSSL uses a state machine, whereSSL_pending()
indicates if the state machine has any pending bytes that have been buffered and are awaiting processing. Since you are never callingSSL_read()
, you are never buffering any data or advancing the state machine.如果 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.