德尔福v10.1柏林。 Indy v10.6.2 OpenSSL v1.0.2h
我有一个在Delphi中设置的表格,用于通过SSL连接(TIdSSLIOHandlerSocketOpenSSL)使用TIdIMAP4进行测试。因为这是为了测试,所以我设置了一个复选框以向我显示当前是否连接了IMAP组件,并且我将IMAP和SSL IOHandler的OnStatus和OnStatusInfo事件都连接到用于更新复选框的代码。该代码很简单:
IsConnectedCB.Checked := imap.Connected;
最终(花了我比我承认的时间更长的时间),我才知道那是破坏SSL连接的原因。这是发生的情况的示例(状态消息的日志):
02:35:13 S: Resolving hostname localhost.
02:35:13 S: Connecting to 127.0.0.1.
02:35:13 S: Connected.
02:35:13 S: SSL status: "before/connect initialization"
02:35:13 S: SSL status: "before/connect initialization"
02:35:13 S: SSL status: "SSLv3 write client hello A"
02:35:13 S: SSL status: "SSLv3 read server hello A"
02:35:43 S: SSL status: "SSLv3 read server certificate A"
02:35:46 S: Disconnecting.
02:35:46 S: Disconnected.
02:35:48 E: SSL negotiation failed.
注意“服务器问候A”之后的时差(有时发生在“客户端问候A”之后)-这是连接尝试超时的地方。
事实证明,对imap.Connected的调用最终会在IOHandler中进行查询,从而使回调处理陷入困境。
解决方案很简单:在回调过程中不要读取Connected属性。 :-)
但是,我希望能够在测试各种长期运行的进程时更新表单状态,而OnStatus / OnStatusInfo事件对此非常方便(而不是将我自己的代码散布在很多更新请求中)。所以...
我的问题是:有没有办法告诉您何时可以安全地测试Connected属性? (在这种情况下为TIdIMAP4.Connected,但我确定该问题必须适用于使用OpenSSL的大多数其他组件。)
最佳答案
有没有办法告诉您何时可以安全地测试Connected属性?
如您所见,Connected
执行读取操作。执行套接字I / O是确定阻塞套接字是否仍然连接且有效的唯一方法。因此,当读取会干扰也需要执行I / O的其他操作的流程时,您不能使用Connected
。
实际上,在大多数情况下,您实际上根本不应该直接使用Connected
。在这种情况下,我建议使用TIdIMAP4.On(Dis)Connected
和/或TIdIMAP4.OnStatus
事件来更新Boolean
变量,然后让其余代码在需要时简单地检查该变量。
关于delphi - 如果在回调过程中测试连接,则Indy OpenSSL问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38380229/