我用 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 可能会导致它将先前的位从管道中清除出去。