php通過socket編程模範smtp協議

php通過socket編程模範smtp協議
SMTP的基礎
基於TCP/IP的因特網協議一般的命令格式都是通過請求/ 應答方式實現的,採用的都是文本信息,所以
處理起來要容易一些。SMTP是簡單郵件傳輸協議的簡稱,它可以實現客戶端向服務器發送郵件的功能。所以
下面所講的命令是指客戶端向服務器發出請求指令,而響應則是指服務器返回給客戶端的信息。
SMTP分爲命令頭和信息體兩部分。命令頭主要完成客戶端與服務器的連接,驗證等。整個過程由多條命
令組成。每個命令發到服務器後,由服務器給出響應信息,一般爲3 位數字的響應碼和響應文本。不同的服
務器返回的響應碼是遵守協議的,但是響應正文本則不必。每個命令及響應的最後都有一個回車符,這樣使
用fputs()和fgets()就可以進行命令與響應的處理了。SMTP的命令及響應信息都是單行的。信息體則是郵件
的正文部分,最後的結束行應以單獨的"."作爲結束行。
客戶端一些常用的SMTP指令爲:
HELO hostname: 與服務器打招呼並告知客戶端使用的機器名字,可以隨便填寫
MAIL FROM: sender_id : 告訴服務器發信人的地址
RCPT TO: receiver_id : 告訴服務器收信人的地址
DATA : 下面開始傳輸信件內容,且最後要以只含有.的特殊行結束
RESET: 取消剛纔的指令,從新開始
VERIFY userid: 校驗帳號是否存在(此指令爲可選指令,服務器可能不支持)
EXPN     驗證給定的郵箱列表是否存在,擴充郵箱列表,也常被禁用
NOOP      無操作,服務器應響應OK
QUIT : 退出連接,結束
RSET      重置會話,當前傳輸被取消
服務器返回的響應信息爲(格式爲:響應碼+空格+解釋):
220 服務就緒(在socket連接成功時,會返回此信息)
221 正在處理
250 請求郵件動作正確,完成(HELO,MAIL FROM,RCPT TO,QUIT指令執行成功會返回此信息)
354 開始發送數據,結束以 .(DATA指令執行成功會返回此信息,客戶端應發送信息)
500 語法錯誤,命令不能識別
550 命令不能執行,郵箱無效
552 中斷處理:用戶超出文件空間
下面給出一個簡單的命令頭(這是在打開socket之後做的),是我向stmp.263.net發郵件的測試結果:
HELO limodou
250 smtp.263.net
MAIL FROM: [email protected]
250 Ok
RCPT TO: [email protected]
250 Ok
DATA
354 End data with .
To: [email protected]
From: [email protected]
Subject: test
From: [email protected]
test
.
QUIT
250 Ok: queued as C46411C5097E0

郵件發送函數定義如下:

<?php

function sendMail( $str_smtp, $int_port, $str_name, $str_ps, $str_aimAddress, $str_title, $str_doc, $str_cc = '' )
{
$_str_result = '';
$_arr_mailContent = array();
$_arr_ccs = '';

$_obj_socket = fsockopen( $str_smtp, $int_port, $errno, $errstr, 60 );
if( !$_obj_socket ) exit( "stmp server connect error! errNo:{$errno}; errMsg:{$errstr}" );
else $_str_result .= 'stmp connect info:'.fgets( $_obj_socket, 512 )."<br/>";

if( !empty( $str_cc ) )
$_arr_ccs = explode( ',', $str_cc );

$_arr_mailContent[] = "HELO Alone\r\n";
$_arr_mailContent[] = "AUTH LOGIN\r\n";
$_arr_mailContent[] = base64_encode( $str_name )."\r\n";
$_arr_mailContent[] = base64_encode( $str_ps )."\r\n";
$_arr_mailContent[] = "MAIL FROM:<{$str_name}>\r\n";
$_arr_mailContent[] = "RCPT TO:<{$str_aimAddress}>\r\n";
if( !empty( $_arr_ccs ) )
{
foreach ( $_arr_ccs as $_str_thisAimAddress )
{
$_str_thisAimAddress = trim( $_str_thisAimAddress );
$_arr_mailContent[] = "RCPT TO:<{$_str_thisAimAddress}>\r\n";
}//end foreach
}//if

$_arr_mailContent[] = "DATA\r\n".
"MIME-Version: 1.0\r\n".
"Content-Type: text/html\r\n".
"To: {$str_aimAddress}\r\n".
( empty( $str_cc ) ? '' : "Cc:{$str_cc}\r\n" ).
"From: {$str_name}\r\n".
"Subject: {$str_title}\r\n".
"X-Mailer:By Redhat (PHP/".phpversion().")\r\n".
"Message-ID: <".md5( time() )."{$str_aimAddress}>\r\n".
"\r\n{$str_doc}\r\n"; //MAIL CONTENT
$_arr_mailContent[] = ".\r\n";
$_arr_mailContent[] = "QUIT\r\n";

foreach ( $_arr_mailContent as $_str_mailContent )
{
fputs( $_obj_socket, $_str_mailContent );
$_str_result .= "<b>{$_str_mailContent}</b>:";
$_str_result .= fgets( $_obj_socket, 512 )."<br/>";
}//end foreach

fclose( $_obj_socket );

return $_str_result;
}//end function sendMail

// echo sendMail( 'ssl://smtp.gmail.com', 465, 'XXXXXXXXXXX', 'XXXX', '[email protected]', 'testMail', '<h1>Hello MySelf</h1>', '[email protected], [email protected]' );
?>



測試輸出結果

<--------------------------------------

stmp connect info:220 mx.google.com ESMTP u12sm1786092tia.3
HELO Alone :250 mx.google.com at your service
AUTH LOGIN :334 VXNlcm5hbWU6
YWxvbmVkaXN0aWFu :334 UGFzc3dvcmQ6
Z20zenl5Mmwx :235 2.7.0 Accepted
MAIL FROM: :250 2.1.0 OK u12sm1786092tia.3
RCPT TO: :250 2.1.5 OK u12sm1786092tia.3
RCPT TO: :250 2.1.5 OK u12sm1786092tia.3
RCPT TO: :250 2.1.5 OK u12sm1786092tia.3
DATA MIME-Version: 1.0 Content-Type: text/html; charset="UTF-8" To: [email protected] Cc:[email protected], [email protected] From: alonedistian Subject: testMail X-Mailer:By Redhat (PHP/5.2.6) Message-ID: <[email protected]>
Hello MySelf

:354 Go ahead u12sm1786092tia.3
. :250 2.0.0 OK 1225875877 u12sm1786092tia.3
QUIT :221 2.0.0 closing connection u12sm1786092tia.3

-------------------------------------------------->
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章