使用ESMTP/SMTP进行邮件发送,遇到一个问题:
  假如附件为图片gif文件,发送没有问题。但是接收后,无法显示图片。敬请高手指点!!!!!
 
  
/*  * Created on 2004-12-21  *  * TODO To change the template for this generated file go to  * Window - Preferences - Java - Code Style - Code Templates  */ 
/**  * @author Administrator  *  * TODO To change the template for this generated type comment go to  * Window - Preferences - Java - Code Style - Code Templates  */ public class FoxMailMain { 
 public static void main(String[] args) {      FoxMail foxMail = new FoxMail("smtp.citiz.net",25);   foxMail.setMailUserName("zhou");   foxMail.setMailUserPass("abcdefgf");   foxMail.setMailTo("[email protected]");   foxMail.setMailFrom("[email protected]");   foxMail.setMailShowTo("tom");   foxMail.setMailShowFrom("Nike");   foxMail.setMailSubject("hello用中文主题");   foxMail.setMailBody("welcome for you. mmm.中文呀.aaa \r\n载来一行");   foxMail.setMailAttachFile(new String[] {"D:\\eclipse_project\\workspace\\PROJECT_email\\src\\pic.gif"});      if(foxMail.sendMail()){    System.out.println("OK.");   }else{    System.out.println("False.");   } 
 } }
 
  FoxMail.java 代码
  import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; 
/*  * Created on 2004-12-21  *  * TODO To change the template for this generated file go to  * Window - Preferences - Java - Code Style - Code Templates  */ 
/**  * @author Administrator  *  * TODO To change the template for this generated type comment go to  * Window - Preferences - Java - Code Style - Code Templates  */ public class FoxMail {    private final static byte LOCATION_TO_SCREEN = 1;//Log信息输出位置 1=输出到屏幕  private final static DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//日志用日期格式  private final static String END_FLAG = "\r\n";//SMTP/ESMTP命令结束标记  private final static String EMAIL_ATTACH_SIGN = "=====att";//邮件附件的表示符号 
 private String smtpServer = null;//邮件发送服务器域名  private int smtpPort = 25;//邮件发送端口  private Socket clientMailSocket;//邮件连接socket  private InputStream inData;//接收数据      private OutputStream outData;//发送数据  private String mailUserName = null;//邮件账户  private String mailUserPass = null;//邮件账户的密码  private String mailTo = null;//邮件发送目标  private String mailFrom = null;//邮件发送人  private String mailSubject = null;//邮件主题  private String mailBody = null;//邮件正文   private String mailShowTo = null;//邮件内容抬头部分-邮件发送目标  private String mailShowFrom = null;//邮件内容抬头部分-邮件发送人  private String[] mailAttachFile = null;//邮件附件对应的本地文件名(包含绝对路径)    /**   * @return Returns the mailAttachFile.   */  public String[] getMailAttachFile() {   return mailAttachFile;  }  /**   * @param mailAttachFile The mailAttachFile to set.   */  public void setMailAttachFile(String[] mailAttachFile) {   this.mailAttachFile = mailAttachFile;  }  /**   * @return Returns the mailShowFrom.   */  public String getMailShowFrom() {   return mailShowFrom;  }  /**   * @param mailShowFrom The mailShowFrom to set.   */  public void setMailShowFrom(String mailShowFrom) {   this.mailShowFrom = mailShowFrom;  }  /**   * @return Returns the mailShowTo.   */  public String getMailShowTo() {   return mailShowTo;  }  /**   * @param mailShowTo The mailShowTo to set.   */  public void setMailShowTo(String mailShowTo) {   this.mailShowTo = mailShowTo;  } 
   /**   * @return Returns the mailBody.   */  public String getMailBody() {   return mailBody;  }  /**   * @param mailBody The mailBody to set.   */  public void setMailBody(String mailBody) {   this.mailBody = mailBody;  }  /**   * @return Returns the mailFrom.   */  public String getMailFrom() {   return mailFrom;  }  /**   * @param mailFrom The mailFrom to set.   */  public void setMailFrom(String mailFrom) {   this.mailFrom = mailFrom;  }  /**   * @return Returns the mailSubject.   */  public String getMailSubject() {   return mailSubject;  }  /**   * @param mailSubject The mailSubject to set.   */  public void setMailSubject(String mailSubject) {   this.mailSubject = mailSubject;  }  /**   * @return Returns the mailTo.   */  public String getMailTo() {   return mailTo;  }  /**   * @param mailTo The mailTo to set.   */  public void setMailTo(String mailTo) {   this.mailTo = mailTo;  }  /**   * @return Returns the mailUserName.   */  public String getMailUserName() {   return mailUserName;  }  /**   * @param mailUserName The mailUserName to set.   */  public void setMailUserName(String mailUserName) {   this.mailUserName = mailUserName;  }  /**   * @return Returns the mailUserPass.   */  public String getMailUserPass() {   return mailUserPass;  }  /**   * @param mailUserPass The mailUserPass to set.   */  public void setMailUserPass(String mailUserPass) {   this.mailUserPass = mailUserPass;  } 
 /**   * Constrctor   * @param _smtpServer   * @param _smtpPort   */  public FoxMail(String smtpServer,int smtpPort){   this.smtpServer = smtpServer;   this.smtpPort = smtpPort;  }       /**    * 写日志信息    * @param _log    * @param _locaton    */   public static void printLogger(String _log,int _locaton){    switch(_locaton){     case LOCATION_TO_SCREEN:      System.out.println("["+dateformat.format(new Date()) + "] "  + _log);      break;     default:      System.out.println("["+dateformat.format(new Date()) + "] "  + _log);    }//switch(_locaton)   }//end      /**    *     * @return    */  public boolean createConnection(){   try {    freeAll();    clientMailSocket = new Socket(smtpServer, smtpPort);    printLogger("Connect to email server " + smtpServer + " on port " + smtpPort,LOCATION_TO_SCREEN);    inData = clientMailSocket.getInputStream();    outData = clientMailSocket.getOutputStream();    fetchCMDResult();//当首次连接服务器后有返回值,必须取走该返回值,否则后面命令的返回值无法判断   } catch (IOException e) {    return false;   }   return true;  }    public static String response(InputStream in){         byte[] buffer = new byte[1024];         StringBuffer inData = new StringBuffer();         int n = 0;   try {     n = in.read(buffer);     inData.append(new String(buffer, 0, n));       } catch (IOException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }   printLogger("CMDResult=" + inData.toString(),LOCATION_TO_SCREEN);   return inData.toString(); 
    }    public static void send(String s, OutputStream out){         byte[] buffer = s.getBytes();         try {    out.write(buffer);    out.flush();   } catch (IOException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }     } 
  public String fetchCMDResult(){   return response(inData);  }    public boolean sendCmd(String _cmd) {   if (_cmd != null) {    send(_cmd,outData);    printLogger("CMD=" + _cmd,LOCATION_TO_SCREEN);   }   return true;  }    /**   * 发送邮件   * 服务器为ESMTP时候采用本方法   * @return true=send ok,false=send failed   */  public boolean sendMail() {      //打开与邮件服务器的连接   if(!createConnection()){    return false;   }      StringBuffer theContent = null; 
  //EHLO   theContent = new StringBuffer();   theContent.append("EHLO ");   theContent.append(smtpServer);   theContent.append(END_FLAG);   sendCmd(theContent.toString());   if(fetchCMDResult().indexOf("250")==-1) return false;   //AUTH LOGIN   theContent = new StringBuffer();   theContent.append("AUTH LOGIN");   theContent.append(END_FLAG);   sendCmd(theContent.toString());   if(fetchCMDResult().indexOf("334")==-1) return false;   //用户名   theContent = new StringBuffer();   theContent.append(Base64Encode(this.mailUserName));   theContent.append(END_FLAG);   sendCmd(theContent.toString());   if(fetchCMDResult().indexOf("334")==-1) return false;   //密码   theContent = new StringBuffer();   theContent.append(Base64Encode(this.mailUserPass));   theContent.append(END_FLAG);   sendCmd(theContent.toString());   if(fetchCMDResult().indexOf("235")==-1) return false;   //邮件发送者   theContent = new StringBuffer();   theContent.append("MAIL FROM:");   theContent.append("<");   theContent.append(this.mailFrom);   theContent.append(">");   theContent.append(END_FLAG);   sendCmd(theContent.toString());   if(fetchCMDResult().indexOf("250")==-1) return false;   //邮件发送目标地址   theContent = new StringBuffer();   theContent.append("RCPT TO:");   theContent.append("<");   theContent.append(this.mailTo);   theContent.append(">");   theContent.append(END_FLAG);   sendCmd(theContent.toString());   if(fetchCMDResult().indexOf("250")==-1) return false;      //邮件内容-开始   theContent = new StringBuffer();   theContent.append("DATA");   theContent.append(END_FLAG);   sendCmd(theContent.toString());   if(fetchCMDResult().indexOf("354")==-1) return false;   //邮件内容-邮件抬头部分   theContent = new StringBuffer();   theContent.append("From:");   theContent.append(this.mailShowFrom);   theContent.append(END_FLAG);   theContent.append("To:");   theContent.append(this.mailShowTo);   theContent.append(END_FLAG);   theContent.append("Subject:");   theContent.append(this.mailSubject);   theContent.append(END_FLAG);   theContent.append("Mime-Version: 1.0");   theContent.append(END_FLAG);    
  theContent.append("Content-Type: multipart/mixed;Boundary=\"");//设置附件表示符   theContent.append(EMAIL_ATTACH_SIGN);   theContent.append("\"");   theContent.append(END_FLAG);//在正文内容前必须有2个END_FLAG标记   theContent.append(END_FLAG);   sendCmd(theContent.toString()); 
  //邮件内容-正文部分   theContent = new StringBuffer();   theContent.append("--");   theContent.append(EMAIL_ATTACH_SIGN);   theContent.append(END_FLAG);   theContent.append("Content-type:text/plain;");   theContent.append(END_FLAG);   theContent.append("Content-Transfer-Encoding: base64");   theContent.append(END_FLAG);   theContent.append(END_FLAG);   theContent.append(Base64Encode(this.mailBody));   theContent.append(END_FLAG);   theContent.append(END_FLAG);   sendCmd(theContent.toString());      //邮件内容-附件部分   //mailAttachFile = null;   if(mailAttachFile!=null && mailAttachFile.length>0){    for(int i=0;i<this.mailAttachFile.length;i++){     //发送附件抬头     theContent = new StringBuffer();     theContent.append("--");     theContent.append(EMAIL_ATTACH_SIGN);     theContent.append(i);     theContent.append(END_FLAG);     theContent.append("Content-Type:image/gif;name=\"aaa.gif\"");     theContent.append(END_FLAG);     theContent.append("Content-Transfer-Encoding:base64");     theContent.append(END_FLAG);     theContent.append("Content-Disposition:attachment;name=\"aaa.gif\"");     theContent.append(END_FLAG);     theContent.append(END_FLAG);     sendCmd(theContent.toString());          //发送附件内容     sendBase64Data(new StringBuffer(Base64Encode(readFile(mailAttachFile[i]))));          //发送附件结束     /*     theContent = new StringBuffer();     theContent.append(END_FLAG);     theContent.append("--");     theContent.append(EMAIL_ATTACH_SIGN);     theContent.append(i);     theContent.append("--");     theContent.append(END_FLAG);     sendCmd(theContent.toString());     */    }       }         //发送附件结束   theContent = new StringBuffer();   theContent.append(END_FLAG);   theContent.append(END_FLAG);   theContent.append("--");   theContent.append(EMAIL_ATTACH_SIGN);   theContent.append("--");   theContent.append(END_FLAG);   sendCmd(theContent.toString());      //邮件内容-结束标记   theContent = new StringBuffer();   theContent.append(END_FLAG);   theContent.append(".");   theContent.append(END_FLAG);   sendCmd(theContent.toString());   if(fetchCMDResult().indexOf("250")==-1) return false;      //退出断开服务器连接   theContent = new StringBuffer();   theContent.append("QUIT");   theContent.append(END_FLAG);   sendCmd(theContent.toString());   fetchCMDResult();      //邮件发送成功后释放资源   freeAll();   theContent = null;      return true;//邮件发送成功  }    /**   * 发送经过Base64编码后的数据   * @param src   */  public void sendBase64Data(StringBuffer srcData){   int LEN_CMD_DATA = 76;   int startIndex = 0;   int totalLength = 0;   if(srcData!=null && srcData.length()>0){    totalLength = srcData.length();    while(true){     if(startIndex+LEN_CMD_DATA<totalLength){      sendCmd(srcData.substring(startIndex,startIndex+LEN_CMD_DATA));      sendCmd(END_FLAG);     }else{      sendCmd(srcData.substring(startIndex,totalLength));      sendCmd(END_FLAG);      break;     }     startIndex = startIndex+LEN_CMD_DATA;    }   }  }    /**   * 释放所有资源   *   */  public void freeAll(){   if(inData!=null){    try {     inData.close();    } catch (IOException e) {     // TODO Auto-generated catch block     e.printStackTrace();    }    inData = null;   }      if(outData!=null){    try {     outData.close();    } catch (IOException e) {     // TODO Auto-generated catch block     e.printStackTrace();    }    outData = null;   }       if(clientMailSocket!=null){    try {     clientMailSocket.close();    } catch (IOException e) {     // TODO Auto-generated catch block     e.printStackTrace();    }    clientMailSocket = null;   }     }      /**   * 读取文件内容   * @param fileName   * @return   */  public String readFile(String fileName){   byte[] fileBuffer = new byte[1024];   int realSize = 0;   StringBuffer readContent = new StringBuffer();   try {    InputStream inFile = new FileInputStream(new File(fileName));    while(true){     realSize = inFile.read(fileBuffer);     if(-1==realSize) break;     readContent.append(new String(fileBuffer,0,realSize));    }   } catch (FileNotFoundException e) {    // TODO Auto-generated catch block    e.printStackTrace();   } catch (IOException e) {    // TODO Auto-generated catch block    e.printStackTrace();   }   return readContent.toString();  } 
    /**      * Base64编码函数      * 将指定的字符串编码为Base64格式的字符串      * @param src      * @return      */  public static String Base64Encode(String src) {   if (src == null || src.length() == 0)    return "";   String EncodingTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";   byte[] Buffer = src.getBytes();   int ReadNow, i, res;   char[] WriteBuf = new char[4];   char[] Buf = new char[3];   String EncodedStr = "";   int ReadIndex = 0;   int Len = Buffer.length;   boolean isEnd;   int BytesWritten = 0;   ReadNow = 0;   do {    isEnd = false;    for (i = 0; i < 3; i++) {     if (ReadIndex >= Len) {      isEnd = true;      ReadNow = i;      break;     }     Buf[i] = (char) (((byte) Buffer[ReadIndex]) & 0x00FF);     ReadIndex = ReadIndex + 1;    }    if (isEnd)     break;    WriteBuf[0] = EncodingTable.charAt((Buf[0] >> 2) & 0x003F);    WriteBuf[1] = EncodingTable      .charAt(((Buf[0] & 3) << 4 | (Buf[1] >> 4)) & 0x003F);    WriteBuf[2] = EncodingTable      .charAt(((Buf[1] & 15) << 2 | (Buf[2] >> 6)) & 0x003F);    WriteBuf[3] = EncodingTable.charAt((Buf[2] & 63) & 0x003F);    for (i = 0; i < 4; i++)     EncodedStr = EncodedStr + WriteBuf[i];    BytesWritten = BytesWritten + 4;    if ((BytesWritten % 76) == 0) {     EncodedStr = EncodedStr + "";    }   } while (ReadNow != 3);   if (ReadNow < 3) {    switch (ReadNow) {    case 1:     WriteBuf[0] = EncodingTable.charAt((Buf[0] >> 2) & 0x003F);     WriteBuf[1] = EncodingTable       .charAt(((Buf[0] & 3) << 4) & 0x003F);     WriteBuf[2] = '=';     WriteBuf[3] = '=';     for (i = 0; i < 4; i++)      EncodedStr = EncodedStr + WriteBuf[i];     break;    case 2:     WriteBuf[0] = EncodingTable.charAt((Buf[0] >> 2) & 0x003F);     WriteBuf[1] = EncodingTable       .charAt(((Buf[0] & 3) << 4 | (Buf[1] >> 4)) & 0x003F);     WriteBuf[2] = EncodingTable       .charAt(((Buf[1] & 15) << 2) & 0x003F);     WriteBuf[3] = '=';     for (i = 0; i < 4; i++)      EncodedStr = EncodedStr + WriteBuf[i];     break;    default:     break;    }   }   return (EncodedStr);  } }
   
 
  |