用socket发邮件,socket发送邮件是指上就是通过客户端向邮件服务器发送以上的命令,从而实现SMTP协议来达到发送邮件的目的,但是于邮件服务器交互的时候,不是一下子就结束了,是一条指令,一条指令的发,返回的结果如果是正常 比如 220,250,334,才能继续向下
看这个东西都是网上看的别人的资料,收集了一些觉得别人说的不错的,另外还有一个RFC文档,将smtp,和扩展的MIME头,将的是非常的详细了.(虽然很多我都看不懂)
stmp协议介绍 算找到的资料中最详细的了
别人的blog
别人的blog
别人的blog(这位兄弟些了好多blog来介绍的)
一些状态码(不是 http 状态码)
- 500 格式错误,命令不可识别(此错误也包括命令行过长)
- 501 参数格式错误
- 502 命令不可实现
- 503 错误的命令序列
- 504 命令参数不可实现
- 211 系统状态或系统帮助响应
- 214 帮助信息
- 220 服务就绪
- 221 服务关闭传输信道
- 421 服务未就绪,关闭传输信道(当必须关闭时,此应答可以作为对任何命令的响应)
- 250 要求的邮件操作完成
- 251 用户非本地,将转发向
- 450 要求的邮件操作未完成,邮箱不可用(例如,邮箱忙)
- 550 要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问)
- 451 放弃要求的操作;处理过程中出错
- 551 用户非本地,请尝试
- 452 系统存储不足,要求的操作未执行
- 552 过量的存储分配,要求的操作未执行
- 553 邮箱名不可用,要求的操作未执行(例如邮箱格式错误)
- 354 开始邮件输入,以.结束
- 554 操作失败
- 535 用户验证失败
- 235 用户验证成功
- 334 等待用户输入验证信息
每次客户端想服务器发一个指令过服务器便会返回相应的相应信息,信息格式为(响应码+空格+解释)
一些常见的相应码为:
简单的过程
1. 建立TCP 连接。
2. 客户端发送HELO命令以标识发件人自己的身份,然后客户端发送MAIL命令;服务器端正希望以OK作为响应,表明准备接收。
3. 客户端发送RCPT命令,以标识该电子邮件的计划接收人,可以有多个RCPT行;服务器端则表示是否愿意为收件人接收邮件。
4. 协商结束,发送邮件,用命令DATA发送。
5. 以“.”号表示结束输入内容一起发送出去,结束此次发送,用QUIT命令退出。
客户端向邮件服务器发送的 常用指令
HELO hostname 与服务器打招呼并且告知服务器客户端使用的机器名,这里可以随便填写;
AUTH LOGIN:user,pass 邮箱帐号,密码
MAIL FROM:sender 告诉邮件服务器发信人的地址;
RCPT TO:receiver 告诉邮件服务器收信人的地址;
DATA 开始发送邮件内容,并且最后只能含有"."为结尾字符的行结束。
QUIT 传输结束,退出连接;
一个简单的例子
<?php
class aMail{
public static $smtp_prot = 25;
public static $debug = true;
public static $crlf = "\r\n";
var $smtp_host;
var $login_name;
var $password;
var $form;
var $to;
var $err;
var $message;
var $socket;
function __construct($options=""){
if($options == "" || !is_array($options)){
return false;
}
foreach($options as $key=>$val){
$this->$key = $val;
}
}
function sendMail(){
$this->socket = fsockopen($this->smtp_host,self::$smtp_prot);
$socket = $this->socket;
$crlf = self::$crlf;
stream_set_blocking($socket,true);
$this->message = fgets($socket,512);
echo $this->message;
if(!$this->print_messsage("/^220/","connect fail")){
return false;
}
fputs($socket,"EHLO 127.0.0.1 ".$crlf);
$this->message = fgets($socket, 512);
if(!$this->print_messsage("/^2/","EHLO fail")){
return false;
}
fputs($socket,"AUTH LOGIN".$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^2/","AUTH LOGIN fail");
fputs($socket,base64_encode($this->login_name).$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^2/","login_name fail");
fputs($socket,base64_encode($this->password).$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^2/","password fail");
fputs($socket,"MAIL FROM: <".$this->from.">".$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^2/","from fail");
fputs($socket,"RCPT TO: <".$this->to.">".$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^334|^2/","to fail");
fputs($socket,"DATA".$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^334|^2/","DATA fail");
$html = implode("",array(
"To: ".$this->to.$crlf,
"From: ".$this->from.$crlf,
"Subject: ".$this->subject.$crlf.$crlf,
$this->content.$crlf.".".$crlf,
));
fputs($socket,$html);
$this->message = fgets($socket, 512);
$this->print_messsage("/^2/","html fail");
fputs($socket, "QUIT".$crlf);
$this->message=fgets($socket,512);
$this->print_messsage("/^2/","QUIT fail");
}
function print_messsage($reg="",$err=""){
$message = $this->message;
if(preg_match($reg,$message)<=0){
$this->err = $err."___".$message."--------------";
echo $err."___".$message."--------------<br>";
return false;
}
if(self::$debug){
echo $this->message."<br>";
}
return true;
}
}
$mail_options = array(
"smtp_host"=>"smtp.sina.com.cn",
"login_name"=>"ycwtt0527",
"password"=>"XXXXX",//填写真实的密码的密码
"from"=>"ycwtt0527@sina.com",
"to"=>"ycwtt0527@sina.com",
"subject"=>"hengheng",
"content"=>"<div style='color:#f00'>asfsadfasdf</div><span>haha</span>",
);
$x = new aMail($mail_options);
$x->sendMail();
?>
运行上面 在页面上会打印
250-irja2-171.sinamail.sina.com.cn
250-8BITMIME
250-SIZE 73400320
250-AUTH PLAIN LOGIN
250 AUTH=PLAIN LOGIN
334 VXNlcm5hbWU6
334 UGFzc3dvcmQ6
235 #2.0.0 OK Authenticated
250 sender ok
看到sender ok 算是发送成功了, 但是对方是否能收的到就不一定了........
发送的内容是<div style='color:#f00'>asfsadfasdf</div><span>haha</span>
发现在收邮件的时候这个标签被转义了,(如果发的是图片,我试了几次都收不到)
这是就要靠MIME扩展来解决这个问题了
大概看了2天相关的内容,结果完全晕了....
MIME的扩展 真心看不大懂 然后看了下phpmailer 就更晕了 光 content-type就有8bit ,7bit ,text/plain,iso-8859-1,base64
然后发邮件又有个中参数 附件 图片 多媒体 等等 n多分枝(因为要根据设置了不同的参数来设置MIME头,在phpmailer里面有create_header,create_body 2个方法,对这边有比较多的判断,我是没兴趣看了)
想看 MIME部分 还是 去看 RFC文档 配合 phpmailer一起看可能效果好点
算了 放弃了 用phpmailer 发了封简单的邮件
看 怎么拼简单的html邮件
如下
To: ycwtt0527@sina.com
From: <ycwtt0527@sina.com>
Subject: hengheng<br>
Return-Path: ycwtt0527@sina.com
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Content-Type: text/html; charset = "iso-8859-1"
<div>asdasdasdasdasdasd</div>
<?php
//RFC文档
class aMail{
public static $smtp_prot = 25;
public static $debug = true;
public static $crlf = "\r\n";
var $smtp_host;
var $login_name;
var $password;
var $form;
var $to;
var $err;
var $message;
var $socket;
public function __construct($options=""){
if($options == "" || !is_array($options)){
return false;
}
foreach($options as $key=>$val){
$this->$key = $val;
}
}
public function sendMail(){
$this->socket = fsockopen($this->smtp_host,self::$smtp_prot);
$socket = $this->socket;
$crlf = self::$crlf;
stream_set_blocking($socket,true);
$this->message = fgets($socket,512);
echo $this->message;
if(!$this->print_messsage("/^220/","connect fail")){
return false;
}
fputs($socket,"EHLO 127.0.0.1 ".$crlf);
$this->message = fgets($socket, 512);
if(!$this->print_messsage("/^2/","EHLO fail")){
return false;
}
fputs($socket,"AUTH LOGIN".$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^2/","AUTH LOGIN fail");
fputs($socket,base64_encode($this->login_name).$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^2/","login_name fail");
fputs($socket,base64_encode($this->password).$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^2/","password fail");
fputs($socket,"MAIL FROM: <".$this->from.">".$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^2/","from fail");
fputs($socket,"RCPT TO: <".$this->to.">".$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^334|^2/","to fail");
fputs($socket,"DATA".$crlf);
$this->message = fgets($socket, 512);
$this->print_messsage("/^334|^2/","DATA fail");
$content = $this->setHtmlBody();
fputs($socket,$content);
$this->message = fgets($socket, 512);
$this->print_messsage("/^2/","html fail");
fputs($socket, "QUIT".$crlf);
$this->message=fgets($socket,512);
$this->print_messsage("/^2/","QUIT fail");
}
public function print_messsage($reg="",$err=""){
$message = $this->message;
if(preg_match($reg,$message)<=0){
$this->err = $err."___".$message."--------------";
echo $err."___".$message."--------------<br>";
return false;
}
if(self::$debug){
echo $this->message."<br>";
}
return true;
}
public function setHtmlBody(){
$content = $this->content;
$crlf = self::$crlf;
$header = array();
$uniq_id = md5(uniqid(time()));
$boundary1 = "b1_" . $uniq_id;
$boundary2 = "b2_" . $uniq_id;
$header[] = "To: ".$this->to.$crlf;
$header[] = "From: <".$this->from.">".$crlf;
$header[] = "Subject: ".$this->subject.$crlf;
$header[] = "Return-Path: ".$this->from.$crlf;
$header[] = "MIME-Version: 1.0".$crlf;
$header[] = "Content-Transfer-Encoding: 8bit".$crlf;
$header[] = "Content-Type: text/html; charset = \"iso-8859-1\"".$crlf.$crlf;
$content = str_replace("\r\n", "\n", $content);
$content = str_replace("\r", "\n", $content);
$content = str_replace("\n", $crlf, $content);
$header[] = $content.$crlf.$crlf;
$str = join("", $header);
$str.= $crlf.".".$crlf;
return $str;
}
}
$mail_options = array(
"smtp_host"=>"smtp.sina.com.cn",
"login_name"=>"ycwtt0527",
"password"=>"xxxxx",//填写密码的
"from"=>"ycwtt0527@sina.com",
"to"=>"ycwtt0527@sina.com",
"subject"=>"hengheng",
"content"=>'<font size="7"><b>hello,world</b></font><br><font size="2">sdfsadasdf</font><br>',
);
$x = new aMail($mail_options);
$x->sendMail();
?>