PHP用socket连接SMTP服务器发送邮件

PHP用socket连接SMTP服务器发送邮件

PHP用socket连接SMTP服务器发送邮件学习实验记录:


分析与SMTP会话的一般流程
1. HELO XXX \r\n //XXX就是自己起个名字,和服务器打个招呼
返回 250 表示成功
2. AUTH LOGIN \r\n //请求与服务器开始验证用户(登陆)
返回 334 表示成功
3. 用户名 \r\n //直接发送用户名PHP中将用户名base64_encode()下
返回 334 表示成功
4. 密码 \r\n //直接发送密码PHP中将密码base64_encode()下
返回235表示成功
5. MAIL FROM \r\n //发件人邮箱地址,一般和上面的用户名密码对应的油箱
返回 250 表示成功
6. RCPT TO \r\n //收件人地址
返回 250 表示成功
7. DATA \r\n //告诉服务器下面开始传输邮件
返回 354 表示成功
8. 传输邮件数据:可以发送邮件了,格式为
From:回信人地址 \r\n //貌似可以写别人的,嘿嘿
Subject:邮件标题 \r\n
To:收件人地址 \r\n
\r\n
正文数据 \r\n
以这个格式发送至服务器,返回250表示发送成功
9. QUIT \r\n 断开连接
返回 221 表示成功
PHP实验程序如下:
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>mail</title>
</head>
<body>
<?php
//以QQ邮箱为例子,要先开通SMTP/POP3功能
$smtp=”smtp.qq.com”;   //SMTP邮件发送服务器
$title=”标题”;     //邮件标题
$username=”qq邮箱帐户”;   //SMTP用户名
$passwd=”邮箱密码”;   //SMTP密码
$mailfrom=”qq邮箱帐户下的地址,也就是自己的QQqq邮箱地址,不能填别人的”; //发送人
$mailfrom1=”别人点回复邮件将回复到此回复邮箱中,可以填写别人的”;        //回复邮件人
$rcptto=”收件箱地址”; //收件人
$mail=”邮件内容”;     //邮件正文
 
smail($smtp,$title,$username,$passwd,$mailfrom,$mailfrom1,$rcptto,$mail);
 
function smail($smtp,$title,$username,$passwd,$mailfrom,$mailfrom1,$rcptto,$mail){
$message=””;
$message .= “正在连接服务器…<br>”;
$link = fsockopen($smtp,25);
if ($link){
 set_socket_blocking($link,true);
 $lastmessage=fgets($link,512);
 
 if (!ereg(“^220”,$lastmessage)){
  $message .= “与服务器连接失败” . $lastmessage . “<br>”;
 }
 else{
  $message .= “与服务器连接成功,服务器就绪:” . $lastmessage . “<br>”;
 
  fputs($link,”HELO phpsetmail”.”\r\n”);
  $lastmessage=fgets($link,2000);
  if (ereg(“^250”,$lastmessage)){
   $message .= “与服务器HELO成功:” .$lastmessage. “<br>”;
  }
  else{
   $message .= “与服务器HELO失败:” .$lastmessage. “<br>”;
  }
 
  fputs($link,”AUTH LOGIN”.”\r\n”);
  $lastmessage=fgets($link,2000);
  if (ereg(“^334”,$lastmessage)){
   $message .= “请求与服务器进行用户验证成功:” .$lastmessage. “<br>”;
  }
  else{
   $message .= “请求与服务器进行用户验证失败:” .$lastmessage. “<br>”;
  }
 
  fputs($link,base64_encode($username).”\r\n”);
  $lastmessage=fgets($link,2000);
  if (ereg(“^334”,$lastmessage)){
   $message .= “与服务器用户验证成功:” .$lastmessage. “<br>”;
  }
  else{
   $message .= “与服务器用户验证失败:” .$lastmessage. “<br>”;
  }
 
  fputs($link,base64_encode($passwd).”\r\n”);
  $lastmessage=fgets($link,2000);
  if (ereg(“^235”,$lastmessage)){
   $message .= “与服务器密码验证成功:” .$lastmessage. “<br>”;
  }
  else{
   $message .= “与服务器密码验证失败:” .$lastmessage. “<br>”;
  }
 
  fputs($link,”MAIL FROM:$mailfrom”.”\r\n”);
  $lastmessage=fgets($link,2000);
  if (ereg(“^250”,$lastmessage)){
   $message .= “与服务器MAIL FROM成功:” .$lastmessage. “<br>”;
  }
  else{
   $message .= “与服务器MAIL FROM失败:” .$lastmessage. “<br>”;
  }
 
  fputs($link,”RCPT TO:$rcptto”.”\r\n”);
  $lastmessage=fgets($link,2000);
  if (ereg(“^250”,$lastmessage)){
   $message .= “与服务器RCPT TO成功:” .$lastmessage. “<br>”;
  }
  else{
   $message .= “与服务器RCPT TO失败:” .$lastmessage. “<br>”;
  }
 
  fputs($link,”DATA”.”\r\n”);
  $lastmessage=fgets($link,2000);
  if (ereg(“^354”,$lastmessage)){
   $message .= “请求与服务器发送邮件数据成功:” .$lastmessage. “<br>”;
   fputs($link,”From:$mailfrom1″ . “\r\n”);
   fputs($link,”Subject:$title” . “\r\n”);
   fputs($link,”To:$rcptto” . “\r\n”);
   fputs($link,”\r\n”);
   fputs($link,$mail . “\r\n”);
   fputs($link,”.” . “\r\n”);
   $lastmessage=fgets($link,2000);
   if (ereg(“^250”,$lastmessage)){
    $message .= “发送邮件数据成功:” .$lastmessage. “<br>”;
   }
   else{
    $message .= “发送邮件数据失败:” .$lastmessage. “<br>”;
   }
 
  }
  else{
   echo “请求与服务器发送邮件数据成功:” .$lastmessage. “<br>”;
  }
 
  fputs($link,”QUIT”.”\r\n”);
  $lastmessage=fgets($link,2000);
  if (ereg(“^221”,$lastmessage)){
   $message .= “与服务器断开连接成功:” .$lastmessage. “<br>”;
  }
  else{
   $message .= “与服务器断开连接失败:” .$lastmessage. “<br>”;
  }
 
 }
 echo “s_”.$message;
}
else{
 echo “err_”;
}
fclose($link);
}
?>
</body>
</html>
例子成功返回如下
s_正在连接服务器…
与服务器连接成功,服务器就绪:220 Esmtp QQ Mail Server
与服务器HELO成功:250 Esmtp OK
请求与服务器进行用户验证成功:334 XXXXXXXXX
与服务器用户验证成功:334 XXXXXXXX
与服务器密码验证成功:235 Authentication successful
与服务器MAIL FROM成功:250 Ok
与服务器RCPT TO成功:250 Ok
请求与服务器发送邮件数据成功:354 End data with .
发送邮件数据成功:250 Ok: queued as
与服务器断开连接成功:221 Bye
附:SMTP基本命令集:
命令       描述
——————————
HELO      向服务器标识用户身份发送者能欺骗,说谎,但一般情况下服务器都能检测到。
MAIL      初始化邮件传输
          mail form :
RCPT      标识单个的邮件接收人;常在MAIL命令后面  可有多个rcpt to:
DATA      在单个或多个RCPT命令后,表示所有的邮件接收人已标识,并初始化数据传输结束。
VRFY      用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令
EXPN      验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用
HELP      查询服务器支持什么命令
NOOP      无操作,服务器应响应OK
QUIT      结束会话
RSET      重置会话,当前传输被取消
——————————

原文链接:,转发请注明来源!

发表评论