smtp.java

来自「apache推出的net包」· Java 代码 · 共 760 行 · 第 1/2 页

JAVA
760
字号
/* * Copyright 2001-2005 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.net.smtp;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.util.Enumeration;import java.util.Vector;import org.apache.commons.net.MalformedServerReplyException;import org.apache.commons.net.ProtocolCommandListener;import org.apache.commons.net.ProtocolCommandSupport;import org.apache.commons.net.SocketClient;/*** * SMTP provides the basic the functionality necessary to implement your * own SMTP client.  To derive the full benefits of the SMTP class requires * some knowledge of the FTP protocol defined in RFC 821.  However, there * is no reason why you should have to use the SMTP class.  The * {@link org.apache.commons.net.smtp.SMTPClient} class, * derived from SMTP, * implements all the functionality required of an SMTP client.  The * SMTP class is made public to provide access to various SMTP constants * and to make it easier for adventurous programmers (or those with * special needs) to interact with the SMTP protocol and implement their * own clients.  A set of methods with names corresponding to the SMTP * command names are provided to facilitate this interaction. * <p> * You should keep in mind that the SMTP server may choose to prematurely * close a connection for various reasons.  The SMTP class will detect a * premature SMTP server connection closing when it receives a * {@link org.apache.commons.net.smtp.SMTPReply#SERVICE_NOT_AVAILABLE SMTPReply.SERVICE_NOT_AVAILABLE } *  response to a command. * When that occurs, the SMTP class method encountering that reply will throw * an {@link org.apache.commons.net.smtp.SMTPConnectionClosedException} * . * <code>SMTPConectionClosedException</code> * is a subclass of <code> IOException </code> and therefore need not be * caught separately, but if you are going to catch it separately, its * catch block must appear before the more general <code> IOException </code> * catch block.  When you encounter an * {@link org.apache.commons.net.smtp.SMTPConnectionClosedException} * , you must disconnect the connection with * {@link org.apache.commons.net.SocketClient#disconnect  disconnect() } * to properly clean up the system resources used by SMTP.  Before * disconnecting, you may check the * last reply code and text with * {@link #getReplyCode  getReplyCode }, * {@link #getReplyString  getReplyString }, * and {@link #getReplyStrings  getReplyStrings}. * <p> * Rather than list it separately for each method, we mention here that * every method communicating with the server and throwing an IOException * can also throw a * {@link org.apache.commons.net.MalformedServerReplyException} * , which is a subclass * of IOException.  A MalformedServerReplyException will be thrown when * the reply received from the server deviates enough from the protocol * specification that it cannot be interpreted in a useful manner despite * attempts to be as lenient as possible. * <p> * <p> * @author Daniel F. Savarese * @see SMTPClient * @see SMTPConnectionClosedException * @see org.apache.commons.net.MalformedServerReplyException ***/public class SMTP extends SocketClient{    /*** The default SMTP port (25). ***/    public static final int DEFAULT_PORT = 25;    // We have to ensure that the protocol communication is in ASCII    // but we use ISO-8859-1 just in case 8-bit characters cross    // the wire.    private static final String __DEFAULT_ENCODING = "ISO-8859-1";    private StringBuffer __commandBuffer;    BufferedReader _reader;    BufferedWriter _writer;    int _replyCode;    Vector _replyLines;    boolean _newReplyString;    String _replyString;    /***     * A ProtocolCommandSupport object used to manage the registering of     * ProtocolCommandListeners and te firing of ProtocolCommandEvents.     ***/    protected ProtocolCommandSupport _commandSupport_;    /***     * The default SMTP constructor.  Sets the default port to     * <code>DEFAULT_PORT</code> and initializes internal data structures     * for saving SMTP reply information.     ***/    public SMTP()    {        setDefaultPort(DEFAULT_PORT);        __commandBuffer = new StringBuffer();        _replyLines = new Vector();        _newReplyString = false;        _replyString = null;        _commandSupport_ = new ProtocolCommandSupport(this);    }    private int __sendCommand(String command, String args, boolean includeSpace)    throws IOException    {        String message;        __commandBuffer.setLength(0);        __commandBuffer.append(command);        if (args != null)        {            if (includeSpace)                __commandBuffer.append(' ');            __commandBuffer.append(args);        }        __commandBuffer.append(SocketClient.NETASCII_EOL);        _writer.write(message = __commandBuffer.toString());        _writer.flush();        if (_commandSupport_.getListenerCount() > 0)            _commandSupport_.fireCommandSent(command, message);        __getReply();        return _replyCode;    }    private int __sendCommand(int command, String args, boolean includeSpace)    throws IOException    {        return __sendCommand(SMTPCommand._commands[command], args, includeSpace);    }    private void __getReply() throws IOException    {        int length;        _newReplyString = true;        _replyLines.setSize(0);        String line = _reader.readLine();        if (line == null)            throw new SMTPConnectionClosedException(                "Connection closed without indication.");        // In case we run into an anomaly we don't want fatal index exceptions        // to be thrown.        length = line.length();        if (length < 3)            throw new MalformedServerReplyException(                "Truncated server reply: " + line);        try        {            String code = line.substring(0, 3);            _replyCode = Integer.parseInt(code);        }        catch (NumberFormatException e)        {            throw new MalformedServerReplyException(                "Could not parse response code.\nServer Reply: " + line);        }        _replyLines.addElement(line);        // Get extra lines if message continues.        if (length > 3 && line.charAt(3) == '-')        {            do            {                line = _reader.readLine();                if (line == null)                    throw new SMTPConnectionClosedException(                        "Connection closed without indication.");                _replyLines.addElement(line);                // The length() check handles problems that could arise from readLine()                // returning too soon after encountering a naked CR or some other                // anomaly.            }            while (!(line.length() >= 4 && line.charAt(3) != '-' &&                     Character.isDigit(line.charAt(0))));            // This is too strong a condition because a non-conforming server            // could screw things up like ftp.funet.fi does for FTP            // line.startsWith(code)));        }        if (_commandSupport_.getListenerCount() > 0)            _commandSupport_.fireReplyReceived(_replyCode, getReplyString());        if (_replyCode == SMTPReply.SERVICE_NOT_AVAILABLE)            throw new SMTPConnectionClosedException(                "SMTP response 421 received.  Server closed connection.");    }    /*** Initiates control connections and gets initial reply. ***/    protected void _connectAction_() throws IOException    {        super._connectAction_();        _reader =            new BufferedReader(new InputStreamReader(_input_,                                                     __DEFAULT_ENCODING));        _writer =            new BufferedWriter(new OutputStreamWriter(_output_,                                                      __DEFAULT_ENCODING));        __getReply();    }    /***     * Adds a ProtocolCommandListener.  Delegates this task to     * {@link #_commandSupport_  _commandSupport_ }.     * <p>     * @param listener  The ProtocolCommandListener to add.     ***/    public void addProtocolCommandListener(ProtocolCommandListener listener)    {        _commandSupport_.addProtocolCommandListener(listener);    }    /***     * Removes a ProtocolCommandListener.  Delegates this task to     * {@link #_commandSupport_  _commandSupport_ }.     * <p>     * @param listener  The ProtocolCommandListener to remove.     ***/    public void removeProtocolCommandistener(ProtocolCommandListener listener)    {        _commandSupport_.removeProtocolCommandListener(listener);    }    /***     * Closes the connection to the SMTP server and sets to null     * some internal data so that the memory may be reclaimed by the     * garbage collector.  The reply text and code information from the     * last command is voided so that the memory it used may be reclaimed.     * <p>     * @exception IOException If an error occurs while disconnecting.     ***/    public void disconnect() throws IOException    {        super.disconnect();        _reader = null;        _writer = null;        _replyString = null;        _replyLines.setSize(0);        _newReplyString = false;    }    /***     * Sends an SMTP command to the server, waits for a reply and returns the     * numerical response code.  After invocation, for more detailed     * information, the actual reply text can be accessed by calling     * {@link #getReplyString  getReplyString } or     * {@link #getReplyStrings  getReplyStrings }.     * <p>     * @param command  The text representation of the  SMTP command to send.     * @param args The arguments to the SMTP command.  If this parameter is     *             set to null, then the command is sent with no argument.     * @return The integer value of the SMTP reply code returned by the server     *         in response to the command.     * @exception SMTPConnectionClosedException     *      If the SMTP server prematurely closes the connection as a result     *      of the client being idle or some other reason causing the server     *      to send SMTP reply code 421.  This exception may be caught either     *      as an IOException or independently as itself.     * @exception IOException  If an I/O error occurs while either sending the     *      command or receiving the server reply.     ***/    public int sendCommand(String command, String args) throws IOException    {        return __sendCommand(command, args, true);    }    /***     * Sends an SMTP command to the server, waits for a reply and returns the     * numerical response code.  After invocation, for more detailed     * information, the actual reply text can be accessed by calling     * {@link #getReplyString  getReplyString } or     * {@link #getReplyStrings  getReplyStrings }.     * <p>     * @param command  The SMTPCommand constant corresponding to the SMTP command     *                 to send.     * @param args The arguments to the SMTP command.  If this parameter is     *             set to null, then the command is sent with no argument.     * @return The integer value of the SMTP reply code returned by the server     *         in response to the command.     * @exception SMTPConnectionClosedException     *      If the SMTP server prematurely closes the connection as a result     *      of the client being idle or some other reason causing the server     *      to send SMTP reply code 421.  This exception may be caught either     *      as an IOException or independently as itself.     * @exception IOException  If an I/O error occurs while either sending the     *      command or receiving the server reply.     ***/    public int sendCommand(int command, String args) throws IOException    {        return sendCommand(SMTPCommand._commands[command], args);    }    /***     * Sends an SMTP command with no arguments to the server, waits for a     * reply and returns the numerical response code.  After invocation, for     * more detailed information, the actual reply text can be accessed by     * calling {@link #getReplyString  getReplyString } or     * {@link #getReplyStrings  getReplyStrings }.     * <p>     * @param command  The text representation of the  SMTP command to send.     * @return The integer value of the SMTP reply code returned by the server     *         in response to the command.     * @exception SMTPConnectionClosedException     *      If the SMTP server prematurely closes the connection as a result     *      of the client being idle or some other reason causing the server     *      to send SMTP reply code 421.  This exception may be caught either     *      as an IOException or independently as itself.     * @exception IOException  If an I/O error occurs while either sending the     *      command or receiving the server reply.     ***/    public int sendCommand(String command) throws IOException    {        return sendCommand(command, null);    }    /***     * Sends an SMTP command with no arguments to the server, waits for a     * reply and returns the numerical response code.  After invocation, for     * more detailed information, the actual reply text can be accessed by     * calling {@link #getReplyString  getReplyString } or     * {@link #getReplyStrings  getReplyStrings }.     * <p>     * @param command  The SMTPCommand constant corresponding to the SMTP command     *                 to send.     * @return The integer value of the SMTP reply code returned by the server     *         in response to the command.     * @exception SMTPConnectionClosedException     *      If the SMTP server prematurely closes the connection as a result     *      of the client being idle or some other reason causing the server     *      to send SMTP reply code 421.  This exception may be caught either     *      as an IOException or independently as itself.     * @exception IOException  If an I/O error occurs while either sending the     *      command or receiving the server reply.     ***/    public int sendCommand(int command) throws IOException    {        return sendCommand(command, null);    }    /***

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?