📄 ch18.htm
字号:
<TR><TD WIDTH=62><CENTER> 503</CENTER></TD><TD WIDTH=528>The last command was sent out of sequeNCe. For example, you might have sent <TT>DATA</TT> before sending <TT>RECV</TT>.</TD></TR><TR><TD WIDTH=62><CENTER> 504</CENTER></TD><TD WIDTH=528>One of the parameters of the last command has not been implemented by the server.</TD></TR><TR><TD WIDTH=62><CENTER> 550</CENTER></TD><TD WIDTH=528>The mailbox that you are trying to reach can't be found or you don't have access rights.</TD></TR><TR><TD WIDTH=62><CENTER> 551</CENTER></TD><TD WIDTH=528>The specified user is not local; part of the text of the message will contain a forwarding address.</TD></TR><TR><TD WIDTH=62><CENTER> 552</CENTER></TD><TD WIDTH=528>The mailbox that you are trying to reach has run out of space. Store the message and try again tomorrow or in a few days-after the user gets a chaNCe to delete some messages.</TD></TR><TR><TD WIDTH=62><CENTER> 553</CENTER></TD><TD WIDTH=528>The mail address that you specified was not syntactically correct.</TD></TR><TR><TD WIDTH=62><CENTER> 554</CENTER></TD><TD WIDTH=528>The mail transaction has failed for unknown causes.</TD></TR></TABLE></CENTER><P><P>Now that you've seen all of the SMTP commands and reply codes,let's see what a typical mail conversation might look like. Inthe following conversation, the '>' lines are the SMTP commandsthat your program issues. The '<' lines are the mail server'sreplies.<BLOCKQUOTE><PRE><B>>HELO</FONT></B><FONT SIZE=2 FACE="Courier"><250 saturn.planet.net Hello medined@planet.net [X.X.X.X],pleased to meet you<B>>MAIL From: <(Rolf D'Barno, 5th Circle Archer)></B><250 <(Rolf D'Barno, 5th Circle Archer)>... Sender ok<B>>RCPT To: <medined@planet.net></B><250 <medined@planet.net>... Recipient ok<B>>DATA</B><354 Enter mail, end with "." on a line by itself<B>>From: (Rolf D'Barno, 5th Circle Archer)>Subject: Arrows>This is line one.>This is line two.</B>>.<250 AAA14672 Message accepted for delivery<B>>QUIT</B><221 saturn.planet.net closing connection</PRE></BLOCKQUOTE><P>The bold lines are the commands that are sent to the server. Someof the SMTP commands are a bit more complex than others. In thenext few sections, the <TT>MAIL</TT>,<TT>RCPT,</TT> and <TT>DATA</TT>commands are discussed. You will also see how to react to undeliverablemail.<H3><A NAME="TheTTFONTSIZEFACECourierMAILFONTTTFONTSIZECommandFONT">The <TT>MAIL</TT>Command</FONT></A></H3><P>The <TT>MAIL</TT> command tells themail server to start a new conversation. It's also used to letthe mail server know where to send a mail message to report errors.The syntax looks like this:<BLOCKQUOTE><PRE>MAIL FROM:<reverse-path></PRE></BLOCKQUOTE><P>If the mail server accepts the command, it will reply with a codeof 250. Otherwise, the reply code will be greater than 400.<P>In the example shown previously<BLOCKQUOTE><PRE><B>>MAIL From:<(medined@planet.net)></FONT></B><FONT SIZE=2 FACE="Courier"><250 <(medined@planet.net)>... Sender ok</PRE></BLOCKQUOTE><P>The reverse-path is different from the name given as the senderfollowing the <TT>DATA</TT> command.You can use this technique to give a mailing list or yourselfan alias. For example, if you are maintaining a mailing list toyour college alumni, you might want the name that appears in thereader's mailer to be <TT>'87 RugRats</TT>instead of your own name.<H3><A NAME="TheTTFONTSIZEFACECourierRCPTFONTTTFONTSIZECommandFONT">The <TT>RCPT </TT>Command</FONT></A></H3><P>You tell the mail server who the recipient of your message isby using the <TT>RCPT</TT> command.You can send more than one <TT>RCPT</TT>command for multiple recipients. The server will respond witha code of 250 to each command. The syntax for the <TT>RCPT</TT>is:<BLOCKQUOTE><PRE>RCPT TO:<forward-path></PRE></BLOCKQUOTE><P>Only one recipient can be named per <TT>RCPT</TT>command. If the recipient is not known to the mail server, theresponse code will be 550. You might also get a response codeindicating that the recipient is not local to the server. If thatis the case, you will get one of two responses back from the server:<UL><LI><B>251 User not local; will forward to <forward-path></B>-Thisreply means that the server will forward the message. The correctmail address is returned so that you can store it for future use.<LI><B>551 User not local; please try <forward-path></B>-Thisreply means that the server won't forward the message. You needto issue another <TT>RCPT</TT> commandwith the new address.</UL><H3><A NAME="TheTTFONTSIZEFACECourierDATAFONTTTFONTSIZECommandFONT">The <TT>DATA</TT>Command</FONT></A></H3><P>After starting the mail conversation and telling the server whothe recipient or recipients are, you use the<TT>DATA</TT> command to send the body of the message. Thesyntax for the <TT>DATA</TT> commandis very simple:<BLOCKQUOTE><PRE>DATA</PRE></BLOCKQUOTE><P>After you get the standard 354 response, send the body of themessage followed by a line with a single period to indicate thatthe body is finished. When the end of message line is received,the server will respond with a 250 reply code.<BR><p><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR><TD><B>Note</B></TD></TR><TR><TD><BLOCKQUOTE>The body of the message can also iNClude several header items like Date, Subject, To, Cc, and From.</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><H3><A NAME="ReportingUndeliverableMail">Reporting Undeliverable Mail</A></H3><P>The mail server is responsible for reporting undeliverable mail,so you may not need to know too much about this topic. However,this information may come in handy if you ever run a list serviceor if you send a message from a temporary account.<P>An endless loop happens when an error notification message issent to a non-existent mailbox. The server keeps trying to senda notification message to the reverse-path specified in the <TT>MAIL</TT>command.<P>The answer to this dilemma is to specify an empty reverse pathin the <TT>MAIL</TT> command of anotification message like this:<BLOCKQUOTE><PRE>MAIL FROM:<></PRE></BLOCKQUOTE><P>An entire mail session that delivers an error notification messagemight look like the following:<BLOCKQUOTE><PRE><B>MAIL FROM:<></FONT></B><FONT SIZE=2 FACE="Courier">250 ok<B>RCPT TO:<@HOST.COM@HOSTW.ARPA></B>250 ok<B>DATA</B>354 send the mail data, end with .<B>Date: 12 May 96 12:34:53From: MEDINED@PLANET.NETTo: ROBIN@UIC.HOST.COMSubject: Problem delivering mail.Robin, your message to JACK@SILVER.COM was notdelivered. SILVER.COM said this: "550 No Such User"</B>.250 ok</PRE></BLOCKQUOTE><H3><A NAME="UsingPerltoSendMail">Using Perl to Send Mail</A></H3><P>I'm sure that by now you've had enough theory and would like tosee some actual Perl code. Without further explanation, Listing18.2 shows you how to send mail.<BR><p><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR><TD><B>Caution</B></TD></TR><TR><TD><BLOCKQUOTE>The script in Listing 18.2 was tested on Windows 95. Some comments have been added to indicate changes that are needed for SunOS 4.1+ and SunOS 5.4+ (Solaris 2). The SunOS comments were supplied by Qusay H. Mahmoud-also known as Perlman on IRC. <FONT FACE="LI Helvetica Light Oblique">Thanks, Qusay!</FONT></BLOCKQUOTE></TD></TR></TABLE></CENTER><P><P><IMG SRC="pseudo.gif" BORDER=1 ALIGN=RIGHT><p><BLOCKQUOTE><I>Turn on the warning compiler option.<BR>Load the </I><TT><I>Socket</I></TT><I>module.<BR>Turn on the strict pragma.<BR>Initialize </I><TT><I>$mail To </I></TT><I>whichholds the recipient's mail address.<BR>Initialize </I><TT><I>$mailServer</I></TT><I>which holds the symbolic name of your mail server.<BR>Initialize </I><TT><I>$mailFrom</I></TT><I>which holds the originator's mail address.<BR>Initialize </I><TT><I>$realName </I></TT><I>whichholds the text that appears in the From header field.<BR>Initialize </I><TT><I>$subject</I></TT><I>which holds the text that appears in the Subject header field.<BR>Initialize </I><TT><I>$body</I></TT><I>which holds the text of the letter.<BR>Declare a signal handler for the Interrupt signal. This handlerwill trap users hitting Ctrl+c or Ctrl+break.<BR>Get the protocol number for the tcp protocol and the port numberfor the smtp service. Windows 95 and NT do not implement the </I><TT><I>getprotobyname()</I></TT><I>or </I><TT><I>getservbyname()</I></TT><I>fuNCtions so default values are supplied.<BR>Initialize </I><TT><I>$serverAddr</I></TT><I>with the mail server's Internet address.<BR>The </I><TT><I>$length</I></TT><I>variable is tested to see if it is defined, if not, then the</I><TT><I>gethostbyname()</I></TT><I>fuNCtion failed.<BR>Create a socket called </I><TT><I>SMTP</I></TT><I>using standard parameters.<BR>Initialize </I><TT><I>$packedFormat</I></TT><I>with format specifiers.<BR>Connect the socket to the port on the mail server.<BR>Change the socket to use unbuffer input/output. Normally, sendsand receives are stored in an internal buffer before being sentto your script. This line of code eliminates the buffering steps.<BR>Create a temporary buffer. The buffer is temporary because itis local to the block surrounded by the curly brackets.<BR>Read two responses from the server. My mail server sends two reponseswhen the connection is made. Your server may only send one response.<BR>If so, delete one of the </I><TT><I>recv()</I></TT><I>calls.<BR>Send the </I><TT><I>HELO</I></TT><I>command. The </I><TT><I>sendSMTP()</I></TT><I>fuNCtion will take care of reading the response.<BR>Send the </I><TT><I>MAIL</I></TT><I>command indicating where messages that the mail server sends back(like undeliverable mail messages) should be sent.<BR>Send the </I><TT><I>RCPT</I></TT><I>command to specify the recipient.<BR>Send the </I><TT><I>DATA</I></TT><I>command.<BR>Send the body of the letter. Note that no reponses are receivedfrom the mail server while the letter is sent.<BR>Send a line containing a single period indicating that you arefinished sending the body of the letter.<BR>Send the </I><TT><I>QUIT</I></TT><I>command to end the conversation.<BR>Close the socket.<BR>Define the </I><TT><I>closeSocket()</I></TT><I>fuNCtion which will act as a signal handler.<BR>Close the socket.<BR>Call </I><TT><I>die()</I></TT><I>to display a message and end the script.<BR>Define the send </I><TT><I>SMTP()</I></TT><I>fuNCtion.<BR>Get the debug parameter.<BR>Get the </I><TT><I>smtp</I></TT><I>command from the parameter array.<BR>Send the </I><TT><I>smtp</I></TT><I>command to </I><TT><I>STDERR</I></TT><I>if the debug parameters were true.<BR>Send the </I><TT><I>smtp</I></TT><I>command to the mail server.<BR>Get the mail server's response.<BR>Send the response to </I><TT><I>STDERR</I></TT><I>if the debug parameter were true.<BR>Split the response into reply code and message, and return justthe reply code.</I></BLOCKQUOTE><HR><BLOCKQUOTE><B>Listing 18.2 18LST02.PL-Sending Mail with Perl<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>#!/usr/bin/perl -wuse Socket;use strict;my($mailTo) = 'medined@planet.net';my($mailServer) = 'mailhost2.planet.net';my($mailFrom) = 'medined@planet.net';my($realName) = "Rolf D'Barno";my($subject) = 'Test';my($body) = "Test Line One.\nTest Line Two.\n";$main::SIG{'INT'} = 'closeSocket';my($proto) = getprotobyname("tcp") || 6;my($port) = getservbyname("SMTP", "tcp") || 25;my($serverAddr) = (gethostbyname($mailServer))[4];if (! defined($length)) { die('gethostbyname failed.');}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -