php - 防止在父级中打开的流套接字被子叉关闭

标签 php sockets cryptography signals parent-child

我有一个工作人员,它使用 pcntl_fork() 跨越新工作,我想在每个 child 中重复使用相同的连接,而不需要在每个 child 中每次都重新连接,目标是获得巨大的性能提升。

  1. 在父级中,我连接到 SMTP 服务,然后 fork 出一个子级。
  2. 第一个 child 成功使用 SMTP 流并可以发送消息。
  3. 当 child 结束时套接字自动关闭。我既不调用任何关闭函数也不调用析构函数,您可以在随附的 repo 示例中看到。
  4. 在此之后, parent 和下一个 child 都不能再使用打开的套接字。

我想防止第 3 个问题,以便下一个 child 可以重用套接字,而无需再次重新连接,因为您知道 SMTP 协议(protocol)很繁琐,重新连接需要时间。 SMTP 服务器可能是 sendmail/sendgrid/Gmail,我尝试了多个提供商,问题出在我的 PHP 而不是 SMTP 协议(protocol)。

我读到信号可能会导致流关闭。有什么办法可以防止这种情况发生。

我有哪些选择?

我正在使用 PHPMailer , 我删除了 close from destructor .我激活了 SMTPKeepAlive 但没有帮助,如您在随附的 repo 示例中所见。如果重要,我使用的是 PHP 5.4

更新 1

我在这个公共(public)仓库中添加了示例代码:https://github.com/pentium10/php_stream_socket_test您可以在 http://www.dispostable.com/inbox/test/ 查看一次性收件箱

您可以在存储库的自述文件中找到输出和 SMTP 响应。我确认从 fork/child/exit 调用中删除任何内容,该示例有效并一个接一个地发送多条消息。

最佳答案

在对您提供的代码进行一些调查之后,您的问题似乎是在您启用 TLS 时出现的。

如果禁用以下行:

$mail->SMTPSecure = 'tls';

您的代码将按预期工作(只要您的 smtp 服务器接受不安全的连接)。

所以这绝对不是套接字或 fork 问题,而可能是违反 TLS 协议(protocol)

如果您尝试发送 RSET 动词(例如,在调用 email() 之前调用 $mail->getSMTPInstance()->reset();),发送第二封邮件时的错误更清楚:

2014-11-04 00:23:18 SMTP ERROR: RSET command failed:
2014-11-04 00:23:18 SMTP NOTICE: EOF caught while checking if connected

我不是加密专家,所以我无法深入了解。但我很确定 stream_socket_client 使用的资源(并用 stream_socket_enable_crypto 包装)存储执行下一个 TLS 事务所需的一些上下文信息。在第一个 child 发送电子邮件后,资源的上下文在 child 的内存中是最新的,但在 parent 的内存中不是。因此,当您尝试使用旧上下文发送另一封电子邮件时,TLS 会中断。

关于php - 防止在父级中打开的流套接字被子叉关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26612780/

相关文章:

php - JSON/PHP 未正确解析

c - ipv6 的 UDP 校验和验证 : how to fetch ipv6 source address from auxilliary data

php - 连接到VB.NET中的源游戏服务器

php - MySQL "CREATE TABLE"查询错误

php - 通过 Imagick 创建/保存 DirectDraw 表面 (DDS) 图像

c++ - 服务器未在 C++ 套接字中接收到尾随 long

java - 使用 PKCS 7 加密技术

.net - 如果启用了 Windows FIPS 合规性策略,为什么不允许 .NET "Managed"加密类?

python - 导入错误 : No module named cryptography. hazmat.backends - Mac 上的 boxsdk

javascript - 在 PHP 中,使用 Header 还是 Javascript 更适合重定向?