如果测试在回调期间连接,则Indy OpenSSL出现问题

时间:2016-07-14 17:08:15

标签: delphi openssl indy

德尔福v10.1柏林。 Indy v10.6.2 OpenSSL v1.0.2h

我有一个在Delphi中设置的表单,用于测试使用带有SSL连接的TIdIMAP4(TIdSSLIOHandlerSocketOpenSSL)。因为这是用于测试,所以我设置了一个复选框来向我显示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的大多数其他组件。)

1 个答案:

答案 0 :(得分:2)

  

有没有办法判断何时测试Connected属性是否安全?

如您所见,Connected执行读取操作。执行套接字I / O是确定阻塞套接字是否仍然连接且有效的唯一方法。因此,在阅读时,您无法使用Connected来干扰还需要执行I / O的其他操作的流程。

事实上,在大多数情况下,你根本不应该直接使用Connected。在这种情况下,我建议使用TIdIMAP4.On(Dis)Connected和/或TIdIMAP4.OnStatus事件来更新Boolean变量,然后让其余代码在需要时检查该变量。