使用SSL的流套接字

Pio*_*ski 25 php sockets ssl smtp

我在PHP 5.6中遇到了流套接字和SSL的问题.似乎SSL正在缓冲输出.在下面的示例中,"ehlo"命令被忽略(服务器没有响应).但是当在"ehlo"之后发送其他内容时,例如在另一次调用中的新行fwrite,服务器发送响应.

$errno = '';
$errstr = '';
$timeout = 5;
$streamContext = stream_context_create();
$host = 'ssl://smtp.some.server.com:465';
$stream = stream_socket_client($host, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $streamContext);
stream_set_blocking($stream, 1);
stream_set_timeout($stream, $timeout);
stream_set_write_buffer($stream, 0);

$fgets = fgets($stream);
print_r($fgets);

fwrite($stream, "ehlo [127.0.0.1]\r\n");

$response = '';
do {
    $line = fgets($stream);
    $response .= $line;
} while (null !== $line && false !== $line && ' ' != $line{3});

print_r($response);

fclose($stream);
Run Code Online (Sandbox Code Playgroud)

我得到了回复:

220 epicserver.net.pl ESMTP IdeaSmtpServer v0.80.2 ready.

(这是从第一次开始print_r).

但是在线后:fwrite($stream, "ehlo [127.0.0.1]\r\n");我添加额外的套接字写:fwrite($stream, "\n");输出正常:

220 epicserver.net.pl ESMTP IdeaSmtpServer v0.80.2 ready.
250-epicserver.net.pl Hello ip-166-242.pl [94.183.162.232], pleased to meet you
250-PIPELINING
250-ENHANCEDSTATUSCODES
250-SIZE
250-8BITMIME
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250 HELP
Run Code Online (Sandbox Code Playgroud)

我已经尝试使用stunnel检查它是否是一个PHP SSL包装器问题,当我$host改为$host = 'localhost:110;'(我的stunnel配置)时,一切都运行完美(没有添加特殊fwrite方法).

有没有人面对这个问题?

小智 1

将第一个 fgets 替换为以下代码,以确保 fgets 正确理解行终止:

$fgets = '';
while (is_resource($stream) && !feof($stream)) {
  $fgets .= fgets($stream); 
}
Run Code Online (Sandbox Code Playgroud)