我想知道如何通过fsockopen/fwrite/fread/fgets
等与PHP服务器正确地进行交互。主要问题似乎是您不知道何时停止阅读命令已发送。
我分析了一些公开的PHP脚本,但没有看到正确的方法。我的下面的脚本对IMO做了两件事:
for($i=0;$i<2;$i++) $s.=fgets($fp, 1024);
)然而,这很慢。在每个命令之后,您需要等待2秒才能启动超时。
// error handling and such missing on purpose to keep it short
$host = "some-MX-host.com";
$commands = array();
$commands[] = "EHLO microsoft.com\r\n";
$commands[] = "MAIL FROM:<>\r\n";
$commands[] = "RCPT TO:<foo@some-MX-host.com>\r\n";
@$fp = fsockopen($host, 25);
stream_set_timeout($fp, 2);
foreach ($commands as $command) {
echo $command;
fwrite($fp, $command);
while ($line = fgets ($fp)) {
print $line;
}
}
fclose($fp);
如何改进?
旁注...某些服务器对RCPT TO:<foo@some-MX-host.com>
中的某些电子邮件地址的响应速度非常慢(通常由于打字错误而无效)。因此,超时2秒通常不够好。因此,为了获得更好的性能,您希望大多数命令(例如1秒)的超时时间更短,RCPT TO
(例如5秒)的超时时间更长。这可能会提高性能,但会使实施变得复杂。
更新2016-05-02
以下修改将减少全局超时,但如果服务器需要一些额外的时间用于某些命令,则仍会等待更长时间。我对这种表现感到非常满意,但我仍然怀疑它没有更优雅。
stream_set_timeout($fp, 1);
foreach ($commands as $command) {
echo $command;
fwrite($fp, $command);
// Wait at most 10 * timeout for the server to respond.
// In most cases the response arrives within timeout time and, therefore, there's no need to wait any longer in such
// cases. However, there are cases when a server is slow to respond. This for-loop will give it some slack.
for ($i = 0; $i < 10; $i++) {
$response = "";
while ($line = fgets($fp)) {
$response .= $line;
}
// Only continue the for-loop if the server hasn't sent anything yet.
if ($response != "") {
break;
}
}
echo $response;
}