PHP stream_socket_enable_crypto 无限期挂起。无论如何要修复?

PHP stream_socket_enable_crypto hangs indefinitely. Anyway to fix?

我有一个 PHP 脚本,用于将电子邮件发送到我的一个网站中的时事通讯列表。

该脚本使用 STARTTLS 进行加密连接,使用以下行建立 SSL 握手:

stream_set_timeout($s, 35, 0);                                  
if(false == stream_socket_enable_crypto($s, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)){
    $msg = "452 failed on tls connection";
} else {
    $in_tls = true;
}

套接字$s设置为阻塞,在发出STARTTLS命令后已经连接到远程服务器,并准备在此阶段开始TLS握手。如您所见,我在握手之前使用 stream_set_timeout 。根据 PHP 文档,它 应该 在 X 秒后中止握手,但似乎没有影响。

现在此代码在 大多数 时间都有效,但我有时 运行 进入 TLS 握手会无限期阻塞的服务器,导致脚本挂起。

我尝试研究非阻塞解决方案,但 none 对我的 PHP 版本有效(我使用 v5.1.6)。

唯一的其他选择是以某种方式监视此行的超时(我不确定这是否可能),或者以某种方式将套接字句柄转移到另一个进程,我可以 运行 使用超时控制方法.

有人知道怎么解决吗?

您可以尝试在流上设置超时,请参阅 php manual stream_set_timeout($s)

When the stream times out, the 'timed_out' key of the array returned by stream_get_meta_data() is set to TRUE, although no error/warning is generated.

还在 PHP 手册

上找到了这个

In case anyone is puzzled, stream_set_timeout DOES NOT work for sockets created with socket_create or socket_accept. Use socket_set_option instead.

Instead of:
<?php
stream_set_timeout($socket,$sec,$usec);
?>

Use:
<?php
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec'=>$sec, 'usec'=>$usec));
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec'=>$sec, 'usec'=>$usec));
?>

更新:这让 OP 解决了这个问题 ini_set('default_socket_timeout', 1);