使用 fsockopen 发送多条消息 - 最后一条消息未发出

使用 fsockopen 发送多条消息 - 最后一条消息未发出

我用 PHP 编写了一个相对简单的邮件投递脚本。以下是实际的投递部分:

        private function SendMail($to, $subj) {
            if(!$this->smtp) { $this->OpenSMTPSock(); }
            fwrite($this->smtp, "MAIL FROM:<[email protected]>\r\n");
            fwrite($this->smtp, "RCPT TO:<$to>\r\n");
            fwrite($this->smtp, "DATA\r\n");
            fwrite($this->smtp, "Received: from email.com by domain.com ; ".date("r")."\r\n");
            fwrite($this->smtp, "Date: ".date("r")."\r\n");
            fwrite($this->smtp, "From:  ".$this->message["display_name"]." <[email protected]>\r\n");
            fwrite($this->smtp, "Reply-to: ".$this->message["reply"]."\r\n");
            fwrite($this->smtp, "Subject: $subj\r\n");
            fwrite($this->smtp, "To: $to\r\n");
            if($this->message["type"] == "H") {
                    fwrite($this->smtp, "content-type: text/html; charset=`iso-8859-1`");
                    fwrite($this->smtp, "\r\n".$this->m_html."\r\n");
            }
            if($this->message["type"] == "T") {
                    fwrite($this->smtp, "\r\n".$this->m_text."\r\n");
            }
            if($this->message["type"] == "B") {
                    echo "Sending multi part message\r\n";
                    $boundary = "_----------=_10167391337129230";
                    fwrite($this->smtp, "content-type: multipart/alternative; boundary=\"$boundary\"\r\n");
                    $outMsg = "This is a multi-part message in MIME format.\r\n";
                    $outMsg .= "--$boundary\r\nContent-Type: text/plain; charset=\"US-ASCII\"\r\n\n";
                    $outMsg .= "Content-Transfer-Encoding: 7bit\r\n\n";
                    $outMsg .= $this->m_text;
                    $outMsg .= "\r\n--$boundary\r\nContent-Type: text/html; charset=\"US-ASCII\"\r\n\n";
                    $outMsg .= $this->m_html;
                    $outMsg .= "\r\n--$boundary--";
                    fwrite($this->smtp, "Message: $outMsg\r\n");
            }
            fwrite($this->smtp, ".\r\n"); //This sends the message
            $this->Log("Message sent to $to");
    }

这里是打开套接字的地方:

        private function OpenSMTPSock() {
            $this->Log("Attempting to open socket connection to SMTP host.");
            $this->smtp = fsockopen("localhost", 25, $errno, $errstr, 30);
            if(!$this->smtp) {
                    $this->Log("Failed to connect to SMTP server The following was observed.");
                    $this->Log("Fatal Error: $errno : $errstr");
                    exit;
            }
            else {
                    $this->Log("Connected to SMTP socket.");
                    fwrite($this->smtp, "HELO email.com\r\n");
            }
    }

*析构函数关闭套接字 基本上,我循环遍历收件人列表并向每个收件人发送自定义消息。它运行正常,直到到达最后一条消息,但最后一条消息没有发送。

如果我将 $this->smtp 更改为 fopen("file", "w"),所有内容都会按预期显示。此外,如果我打开该文件并将内容转储到:telnet localhost 25 所有消息都会正常发出。此外,如果我在 PHP 脚本中打开“文件”,并将行写入套接字,所有消息都会按预期发出。

我无论如何也想不出这里出了什么问题。救命啊!

答案1

你的析构函数是否发送了 QUIT 命令?我同意,如果一切都按照你的想法发生,邮件应该如果服务器返回“250 OK”,则发送该消息(这是在您发送最后一条消息之后发送的吗?您正在调试这个消息吗?)。尝试在代码中紧接着“CRLF.CRLF”添加以下内容:

fwrite($this->smtp, "NOOP\r\n");

也许您的类与缓冲区之间存在某种竞争条件,该类在发送缓冲区中的最终数据之前关闭了连接。在链中添加虚拟 NOOP 可能会导致它将先前的位从管道中清除出去。

相关内容