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. Bundle捆绑压缩技术

    Bundle捆绑压缩技术由命名空间System.Web.Optimization中的类提供.顾名思义,这些类是用来优化Web页面性能的,它们通过压缩文件大小,捆绑文件(把多个文件合成一个下载文件)来实 ...

  2. DELL T110 II 系统安装总结

    DELL T110 II  系统安装总结 1.RAID制作:https://jingyan.baidu.com/article/a3aad71ac4ce98b1fb0096bc.html 2.系统安装 ...

  3. 代码正常,junit却报错原因及解决方法

    junit测试,不能有参数 和static,去掉static测试正常;

  4. xadmin列表页添加自定义工具栏toolbar

    通过xadmin的Plugin实现,adminx.py中 class Link2AdminPlugin(BaseAdminPlugin): link_2_admin = False def init_ ...

  5. CF 439C(251C题)Devu and Partitioning of the Array

    Devu and Partitioning of the Array time limit per test 1 second memory limit per test 256 megabytes ...

  6. 负载均衡(LB)具体解释

    二.LB LoadBalance就是把负载均衡分配到集群的各个节点,从而提高总体的吞吐能力.Oracle 10g RAC提供了两种手段来实现负载,其一是通过Connection Balancing.依 ...

  7. DbVisualizer Personal 中文乱码问题的通用解决方法

    在SQL Commander中,sql语句中假设有中文.显示是口. 解决的方法例如以下: 在Tools->Tool Properties->General->Appearance-& ...

  8. android-从官网下拉源码(ubuntu)

    今天终于成功的从谷歌官网上下载了android 源码.中间折腾了好久,最终总算有所收获 1.下载repo curl https://storage.googleapis.com/git-repo-do ...

  9. c++中sizeof()的用法介绍

    1.      定义 sizeof是一个操作符(operator). 其作用是返回一个对象或类型所占的内存字节数. 2.      语法 sizeof有三种语法形式: 1)  sizeof (obje ...

  10. Spark 1.6.1 源码分析

    由于gitbook网速不好,所以复制自https://zx150842.gitbooks.io/spark-1-6-1-source-code/content/,非原创,纯属搬运工,若作者要求,可删除 ...