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. ToF相机学习笔记之基本知识

    ToF相机属于一种非接触式光学传感器,通过计算发射激光的飞行时间获取对应像素的深度信息.就非接触式距离测量方法而言,其分类可用下表表示如下: 1.1 ToF传感器基础 一个逐点式的ToF传感器采用了雷 ...

  2. 如何在 Highcharts 图中当所占百分比为 0 时不显示0%

    解决办法其实很简单,将enabled属性改为false即可: dataLabels: { enabled: false } 完成之后的显示如下

  3. eclipse 安装javaEE插件 和html\xml\jsp编辑器

    1 在Eclipse中菜单help选项中选择install new software选项 2 在work with 栏中输入 http://download.eclipse.org/releases/ ...

  4. CSUOJ 1638 Continued Fraction

    1638: Continued Fraction Time Limit: 1 Sec  Memory Limit: 128 MB Description Input Output Sample Inp ...

  5. Jetty 类载入问题处理

    前几日使用 Jetty (9.2)部署公司一个 web 项目,这个项目原本部署在 Tomcat server上,一切正常,可是部署到 Jetty 后,启动报错.关键错误信息为"java.la ...

  6. iOS定制改动navigation的backbutton

    iOS开发中.navigation的返回button是英文"back".想改动成中文"返回"或者自己定义的文字.这么简单的事情却折腾了小半个小时.原来是被lef ...

  7. LeetCode102 Binary Tree Level Order Traversal Java

    题目: Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to ri ...

  8. view-activity跟控件在onkey事件上的传递关系

    android 中Activity跟View对于键盘的监听,主要有以下几个方法 //按键按下 public boolean onKeyDown(int keyCode, KeyEvent event) ...

  9. 65.Express---express-session

    转自:https://blog.csdn.net/zhangweiwtmdbf/article/details/50723816 第一部分 session概述 1.1 session 是什么? Ses ...

  10. typeof 和 instanceof 的区别

    在JavaScript中我们想得到一个变量的类型,我们一般会用typeof 得到这个类型的 字符串,但是对于引用类型,typeof始终会返回一个"object",在我们js中有十个 ...