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      重置会话,当前传输被取消

——————————

PHP用socket连接SMTP服务器发送邮件的更多相关文章

  1. Linux 上使用 Gmail SMTP 服务器发送邮件通知

    导读 假定你想配置一个 Linux 应用,用于从你的服务器或桌面客户端发送邮件信息.邮件信息可能是邮件简报.状态更新(如 Cachet).监控警报(如 Monit).磁盘时间(如 RAID mdadm ...

  2. 微软BI 之SSIS 系列 - 使用 Script Task 访问非 Windows 验证下的 SMTP 服务器发送邮件

    原文:微软BI 之SSIS 系列 - 使用 Script Task 访问非 Windows 验证下的 SMTP 服务器发送邮件 开篇介绍 大多数情况下我们的 SSIS 包都会配置在 SQL Agent ...

  3. JavaMail SMTP服务器发送邮件程序示例 java通过dns服务器解析ip地址

    /** * JavaMail SMTP服务器发送邮件程序示例 * 扮演SMTP服务器角色与邮件客户端软件最大的区别就是: * SMTP服务器需要解析不同接收人邮件地址主机名对应的SMTP服务器主机名 ...

  4. Ubuntu 使用 heirloom-mail 调用外部邮箱 SMTP 服务器发送邮件

    使用本地服务发邮件,经常被过滤掉而且占用资源,发送成功率不高.所以使用外部SMTP服务器发送邮件成为了需求. SMTP认证的目的是为了使用户避免受到垃圾邮件的侵扰,简单地说就是要求必须在提供了账户名和 ...

  5. CentOS7配置mailx使用外部smtp服务器发送邮件

    转自huskiesir的博客: 发送邮件的两种方式: 1.连接现成的smtp服务器去发送(此方法比较简单,直接利用现有的smtp服务器比如qq.新浪.网易等邮箱,只需要直接配置mail.rc文件即可实 ...

  6. centeros 7配置mailx使用外部smtp服务器发送邮件

    发送邮件的两种方式: 1.连接现成的smtp服务器去发送(此方法比较简单,直接利用现有的smtp服务器比如qq.新浪.网易等邮箱,只需要直接配置mail.rc文件即可实现) 2.自己搭建私有的smtp ...

  7. C#利用SMTP服务器发送邮件

    使用.net(C#)发送邮件学习手册(带成功案例) 1.了解发送邮件的三种方式 2.实例介绍使用client.DeliveryMethod = System.Net.Mail.SmtpDelivery ...

  8. [教程] Windows Server 2008 R2架设SMTP服务器发送邮件教程

    Windows Server 2008 R2 架设SMTP服务器实现邮件发送 目的:架设SMTP服务器实现邮件发送. 一.域名设置 添加“邮件交换记录(MX)”: Newjs.cn           ...

  9. Java通过socket实现smtp协议发送邮件

    import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.IOException;import java ...

随机推荐

  1. Servlet之doPost获取表单参数

    /** * 获取表单参数 */ private void readForm() { // TODO Auto-generated method stub Enumeration e = request ...

  2. jython awt demo

    jython awt demo : """\ Create a panel showing all of the colors defined in the pawt.c ...

  3. 织梦(dedecms)彩色标签云(tag)随机颜色和字体大小

    1.选择你所要加页面的模板,一般是在首页index.htm 加上如下代码 01 <!-- /下面开始tag标签云 --> 02 <dl class="tbox light& ...

  4. 网络地图WebMap介绍

    WebMap是从ArcGIS Online或者ArcGIS for Portal item上获取显示到用户的界面中. 需要的是地图的ID. 创建一个新的网络地图需要设置ID号,然后再用地图底图MapV ...

  5. Java基础关于Map(字典)的方法使用

    Java基础关于Map(字典)的方法使用 java中一般用map与hashmap来创建一个key-value对象 使用前提是要导入方法包: import java.util.HashMap: impo ...

  6. python调用Java代码,完毕JBPM工作流application

    1.缘由 有一庞大Python django webproject,要引入工作流引擎,像OA一样.方便的流程控制与管理.Python或django关于工作流的开源插件,稀少,并且弱爆了,终于选用jav ...

  7. The incident LOST_EVENTS occured on the master. Message: error writing to the binary log, Error_code

    1 mysq error日志报错例如以下: 2014-05-12 11:29:54 22977 [ERROR] Slave SQL: The incident LOST_EVENTS occured ...

  8. jquery07

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  9. Android照片墙完整版,完美结合 内存方案 LruCache 和 硬盘方案 DiskLruCache

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/34093441 在上一篇文章当中,我们学习了DiskLruCache的概念和基本用法 ...

  10. js中常用的对象—String的属性和方法

    今天说一下,js中常用的内置对象——String对象它有以下几个常用的属性:lengthprototype 有以下几个常用的方法:parseInt()转换为数字parseFloat()转换为数字,支持 ...