当前位置:Linux教程 - Linux - 也谈用Socket发送电子邮件

也谈用Socket发送电子邮件

作者:尚轩

在phpuser.com的文章中limodou大哥发表了文章《用Socket发送电子邮件》。在smtp协议中邮件的结束是以 . 结束,但是要和内容不在同一行,否则,邮件服务器认为邮件还没有结束,服务器还在等待数据的上传!下面请看outlook发的邮件内容:

>>> [email protected]
<<< smileyou@localhost

X-Server: Advanced Direct Remailer (www.elcomsoft.com)
Message-ID: <002d01c04b32$60196960$0300a8c0@zyh>
From: ""zyh""
To:
Subject: Fw: aa
Date: Sat, 11 Nov 2000 00:22:09 +0800
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary=""----=_NextPart_000_002A_01C04B75.6E2BE080""
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.00.2615.200
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2615.200

This is a multi-part message in MIME format.

------=_NextPart_000_002A_01C04B75.6E2BE080
Content-Type: text/plain;
charset=""gb2312""
Content-Transfer-Encoding: base64

DQphYQ0K

------=_NextPart_000_002A_01C04B75.6E2BE080
Content-Type: text/html;
charset=""gb2312""
Content-Transfer-Encoding: base64

PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv
L0VOIj4NCjxIVE1MPjxIRUFEPg0KPE1FVEEgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PWdi
MjMxMiIgaHR0cC1lcXVpdj1Db250ZW50LVR5cGU+DQo8TUVUQSBjb250ZW50PSJNU0hUTUwgNS4w
MC4yNjE0LjM1MDAiIG5hbWU9R0VORVJBVE9SPg0KPFNUWUxFPjwvU1RZTEU+DQo8L0hFQUQ+DQo8
Qk9EWSBiZ0NvbG9yPSNmZmZmZmY+DQo8RElWPiZuYnNwOzwvRElWPg0KPERJVj48Rk9OVCBzaXpl
PTI+YWE8L0ZPTlQ+PC9ESVY+PC9CT0RZPjwvSFRNTD4NCg==

------=_NextPart_000_002A_01C04B75.6E2BE080--

.


大家可以看到最后是换行+.+换行结束的!而且内容使用了base64编码,在limodou的文章中,没有将内容编码,
所以,有的朋友就无法看到信件的内容!我们将内容解码,得到的内容是""aa""这两个字母。那我们怎么让
上传的内容最后换行+.+换行呢?
其实很简单,fputs上去的数据直接换行就可以了:请看下面的例子:


$smtpserver=""localhost"" ;
$fp = fsockopen($smtpserver, 25, &$errno, &$errstr, 10);

echo ($hostreply=fgets($fp,128));

$server_name=strstr(ltrim($hostreply),"" "") ;
$server_name=substr(ltrim($server_name),0,strlen ($server_name )-12) ;
echo ""
server_name:"".$server_name.""
"" ;
fputs($fp,""HELO $server_name n"");

$hostreply=fgets($fp,128);
fputs($fp,""MAIL FROM: [email protected]"") ;
echo($hostreply=fgets($fp,128));
echo ""
--------------------------
"";
fputs($fp,""RCPT TO: [email protected]"") ;
echo($hostreply=fgets($fp,128)) ;




fputs($fp,""DATAn"") ;
echo($hostreply=fgets($fp,128)) ;
echo ""
--------------------------
n"";
$mail_from=""[email protected]"";
$mail_to=""[email protected]"";
$subject=""test"";
$mail_from=""From: <$mail_from>"";
$mail_to=""TO: <$mail_to>"";
$subject=""Subject: $subject"";
$message=base64_encode(""this is a test leter"");
fputs($fp,$mail_from.""
"") ;
fputs ($fp ,$mail_to.""
"");
fputs ($fp,$subject.""
"");
fputs ($fp,$message.""

"");
fputs ($fp,""."");
fputs ($fp,""
"");
echo($hostreply=fgets($fp,128));
fputs($fp,""QUIT"") ;

fclose($fp) ;
?>

大家看到,fputs邮件内容是直接换行的,而不是用php中""n""或者""r""的,可是一部分却以""n""换行的,
我没法搞懂那部分,哪位明白的话告诉小弟一声。这个邮件就这样发出去了。


好,下面让我们看一个带附件的邮件的发送情况。下面是附件为line.gif,主题为“附件”,内容为“附件”
的邮件发送到smtp服务器的数据内容:

>>> [email protected]
<<< [email protected]

X-Server: Advanced Direct Remailer (www.elcomsoft.com)
Message-ID: <000901c04b3c$b7aa82e0$0300a8c0@zyh>
From: ""zyh""
To:
Subject: =?gb2312?B?uL28/g==?=
Date: Sat, 11 Nov 2000 01:36:11 +0800
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary=""----=_NextPart_000_0005_01C04B7F.C5A30960""
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.00.2615.200
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2615.200

This is a multi-part message in MIME format.

------=_NextPart_000_0005_01C04B7F.C5A30960
Content-Type: multipart/alternative;
boundary=""----=_NextPart_001_0006_01C04B7F.C5AC3120""


------=_NextPart_001_0006_01C04B7F.C5AC3120
Content-Type: text/plain;
charset=""gb2312""
Content-Transfer-Encoding: base64

uL28/g0K

------=_NextPart_001_0006_01C04B7F.C5AC3120
Content-Type: text/html;
charset=""gb2312""
Content-Transfer-Encoding: base64

PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv
L0VOIj4NCjxIVE1MPjxIRUFEPg0KPE1FVEEgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PWdi
MjMxMiIgaHR0cC1lcXVpdj1Db250ZW50LVR5cGU+DQo8TUVUQSBjb250ZW50PSJNU0hUTUwgNS4w
MC4yNjE0LjM1MDAiIG5hbWU9R0VORVJBVE9SPg0KPFNUWUxFPjwvU1RZTEU+DQo8L0hFQUQ+DQo8
Qk9EWSBiZ0NvbG9yPSNmZmZmZmY+DQo8RElWPjxGT05UIHNpemU9Mj64vbz+PC9GT05UPjwvRElW
PjwvQk9EWT48L0hUTUw+DQo=

------=_NextPart_001_0006_01C04B7F.C5AC3120--

------=_NextPart_000_0005_01C04B7F.C5A30960
Content-Type: image/gif;
name=""line.gif""
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename=""line.gif""

R0lGODlhugEHAJEAAP9/D////wAAAAAAACwAAAAAugEHAEACfIyPqcvtD6OctNqLs968+w+GDQAY
pFkGp5qubgujMju/dUznto7vfg+8CXnDXzFITBqVyKWzCT1KmdNnNUrNWnOirvcLDovH5LL5jE6r
1+y2+w2Py+f0uv2Ol2/3WP71r9UnCOgXSDhomFi4iMh4+KjYiJRHWWl5iZnJUAAAOw==

------=_NextPart_000_0005_01C04B7F.C5A30960--

.

大家可以看到subject部分变化了,还有变化的有X-Priority: 3上面的Content-Type变了,
在phpuser的站长hunte的文章《用PHP发送有附件的电子邮件》中了解到以下的内容:
这个头告诉邮件程序电子邮件是由一个以上的部分组成的。不含附件的邮件只有一个部分:消息本身。
带附件的电子通常至少由两部分组成:消息和附件。这样,带两个附件的邮件由三部分组成:消息,第一
个附件和第二个附件。

带附件的电子邮件的不同部分之间用分界线来分隔。分界线在Content-type头中定义。邮件的每个新部分
以两个连字号(--)和分界线开始。最后一个分界线后也有两个连字号,表示这个邮件中没有其它的部分了。

在每个分界线后有一些行,用来告诉邮件程序这个部分的内容的类型。比如,看看上面例子中第一个分界
线后面的两行--以Content-type: text/plain开头的行。这些行说明后面的部分是gb2312字符集的纯文本。跟在第二
个分界线后的行告诉邮件程序现在的部分是一个HTML文件,它的名字是""attachment.html""。

Content-disposition这持告诉邮件程序如果可能就以内嵌的方式显示附件。现在新的邮件程序会在消息后
显示HTML的内容。如果Content-disposition被设为attachment,那么邮件程序就不会显示HTML文件的内容
,而是显示一个连接到文件的图标(或其它的类似的东西)。收件人要看附件的内容,必须点击这个图标。
一般情况下,如果附件是一些文本(包含HTML),Content-disposition会被设为inline,这是因为
现在大部分邮件程序能够不借助其它浏览器而直接显示附件(文本)的内容。如果附件不是文本(比如
图片或其它类似的内容),Content-disposition就设为attachment。


邮件的内容的content-type是text/html,图片的content-type是image/gif,而且多用了base64编码。现在我们将
其改进一下,



if ($submit){
/*--------------------
#打开附件、读取内容、并编码、分割
$fpfile = fopen($file, ""r"");
$read = fread($fpfile, filesize($file));
$read = base64_encode($read);
$read = chunk_split($read);
----------------------*/


/*-----------------
#获得文件的类型
if ($file_type){
$mimeType = $file_type;
}
else {$mimeType = ""application/unknown"";}
--------------------*/