• C#基于SMTP协议和SOCKET通信,实现邮件内容和附件的发送,并可隐藏收件人


    经过几天的努力,从完全不懂SMTP到折腾出个可以发送邮件内容和附件的DEMO。话少说,直接上代码。


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net.Sockets;
    using System.IO;
    
    namespace UtilSp.ClassLib
    {
        public class SmtpSp
        {
            #region Member
    
            #region boundary normal Property
            private string boundary_ = Guid.NewGuid().ToString();//Generate unique boundary.
            public string boundary_pro
            {
                get
                {
                    return boundary_;
                }
                set
                {
                    boundary_ = value;
                }
            }
            #endregion
    
            #region exception  Property
            private Exception exception_ = null;
            public Exception exception_pro
            {
                get
                {
                    return exception_;
                }
                set
                {
                    exception_ = value;
                }
            }
            #endregion
    
            #region encoding_smtp normal Property
            private Encoding encoding_smtp_ = Encoding.ASCII;//smtp encoding must be ascii.
            private Encoding encoding_smtp_pro
            {
                get
                {
                    return encoding_smtp_;
                }
            }
            #endregion
    
            #region encoding_subject normal Property
            private Encoding encoding_subject_ = Encoding.UTF8;
            public Encoding encoding_subject_pro
            {
                get
                {
                    return encoding_subject_;
                }
                set
                {
                    encoding_subject_ = value;
                }
            }
            #endregion
    
            #region encoding_content normal Property
            private Encoding encoding_content_ = Encoding.GetEncoding("gb2312");
            public Encoding encoding_content_pro
            {
                get
                {
                    return encoding_content_;
                }
                set
                {
                    encoding_content_ = value;
                }
            }
            #endregion
    
            #region receiveInfo normal Property
            private string receiveInfo_ = "";
            public string receiveInfo_pro
            {
                get
                {
                    return receiveInfo_;
                }
                set
                {
                    receiveInfo_ = value;
                }
            }
            #endregion
    
            #region socket normal Property
            private Socket socket_;
            public Socket socket_pro
            {
                get
                {
                    return socket_;
                }
                private set
                {
                    socket_ = value;
                }
            }
            #endregion
    
            #endregion
    
            private sealed class SMTP_BACKS
            {
                public const string SERVER_READY_OK = "220";
                public const string OPERATE_COMPLETE = "250";
                public const string AUTH_LOGIN_OK = "334";
                public const string USER_NAME_LOGIN_OK = "334";
                public const string PASSWORD_LOGIN_OK = "235";
                public const string DATA_OK = "354";
            }
    
            private sealed class SMTP_CMD
            {
                public const string AUTH_LOGIN = "auth login
    ";
                public const string MAIL_FROM = "mail from:";
                public const string RCPT_TO = "rcpt to:";
                public const string SEND_BODY = "data
    ";
                public const string VERIFY = "ehlo hello
    ";
            }
    
            public sealed class MailInfo
            {
                #region attachments normal Property
                private List<string> attachments_ = new List<string>();
                public List<string> attachments_pro
                {
                    get
                    {
                        return attachments_;
                    }
                    set
                    {
                        attachments_ = value;
                    }
                }
                #endregion
    
                #region content normal Property
                private string content_ = "";
                public string content_pro
                {
                    get
                    {
                        return content_;
                    }
                    set
                    {
                        content_ = value;
                    }
                }
                #endregion
    
                #region password normal Property
                private string password_ = "";
                public string password_pro
                {
                    get
                    {
                        return password_;
                    }
                    set
                    {
                        password_ = value;
                    }
                }
                #endregion
    
                #region receiverAddresses normal Property
                private List<string> receiverAddresses_ = new List<string>();
                public List<string> receiverAddresses_pro
                {
                    get
                    {
                        return receiverAddresses_;
                    }
                    set
                    {
                        receiverAddresses_ = value;
                    }
                }
                #endregion
    
                #region senderAddress normal Property
                private string senderAddress_ = "";
                public string senderAddress_pro
                {
                    get
                    {
                        return senderAddress_;
                    }
                    set
                    {
                        senderAddress_ = value;
                    }
                }
                #endregion
    
                #region subject normal Property
                private string subject_ = "";
                public string subject_pro
                {
                    get
                    {
                        return subject_;
                    }
                    set
                    {
                        subject_ = value;
                    }
                }
                #endregion
    
                #region userName normal Property
                private string userName_ = "";
                public string userName_pro
                {
                    get
                    {
                        return userName_;
                    }
                    set
                    {
                        userName_ = value;
                    }
                }
                #endregion
            }
    
            #region send Function
            public bool send(string mailHostIP, int port, MailInfo mailInfo)
            {
                try
                {
                    exception_pro = null;
                    if (!isLegal(mailHostIP, port, mailInfo))
                    {
                        return false;
                    }
                    socket_pro = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    socket_pro.Connect(mailHostIP, port);
                    if (!socket_pro.Connected)
                    {
                        socket_pro.Close();
                        exception_pro = new Exception(Tip.ConnectFail);
                        return false;
                    }
    
                    if (!isServerReady())
                    {
                        exception_pro = new Exception(Tip.ServerReadyFail + analyReceiveError());
                        socket_pro.Close();
                        return false;
                    }
    
                    if (!verify())
                    {
                        exception_pro = new Exception(Tip.VerifyFail + analyReceiveError());
                        socket_pro.Close();
                        return false;
                    }
    
                    if (!authLogin())
                    {
                        exception_pro = new Exception(Tip.AuthLoginFail + analyReceiveError());
                        socket_pro.Close();
                        return false;
                    }
    
                    if (!userNameLogin(mailInfo.userName_pro))
                    {
                        exception_pro = new Exception(Tip.UserNameLoginFail + analyReceiveError());
                        socket_pro.Close();
                        return false;
                    }
    
                    if (!passowrdLogin(mailInfo.password_pro))
                    {
                        exception_pro = new Exception(Tip.PasswordLoginFail + analyReceiveError());
                        socket_pro.Close();
                        return false;
                    }
    
                    if (!mailFrom(mailInfo.senderAddress_pro))
                    {
                        exception_pro = new Exception(Tip.MailFromFail + analyReceiveError());
                        socket_pro.Close();
                        return false;
                    }
    
                    if (!rcptTo(mailInfo.receiverAddresses_pro))
                    {
                        exception_pro = new Exception(Tip.RcptToFail + analyReceiveError());
                        socket_pro.Close();
                        return false;
                    }
    
                    if (!sendMail(mailInfo))
                    {
                        exception_pro = new Exception(Tip.SendMailFail + analyReceiveError());
                        socket_pro.Close();
                        return false;
                    }
    
                    socket_pro.Close();
                    return true;
                }
                catch (System.Exception ex)
                {
                    exception_pro = ex;
                    return false;
                }
            }
    
            private string analyReceiveError()
            {
                if (string.IsNullOrEmpty(receiveInfo_pro))
                {
                    return Tip.ReceiveInfoEmpty;
                }
                return receiveInfo_pro;
            }
    
            #endregion
    
            private int socketSend(string sendStr)
            {
                byte[] sendBuffer = encoding_smtp_pro.GetBytes(sendStr);
                return socket_pro.Send(sendBuffer);
            }
            private string receive()
            {
                byte[] receiveData = new byte[10240];
                int receiveLen = socket_pro.Receive(receiveData);
                receiveInfo_pro = encoding_smtp_pro.GetString(receiveData, 0, receiveLen);
                Console.WriteLine(receiveInfo_pro);
                return receiveInfo_pro;
            }
    
            #region send ready functions
    
            #region isLegal Function
            public bool isLegal(string mailHostIP, int port, MailInfo mailInfo)
            {
                if (!IpPortSp.isPort(port.ToString()))
                {
                    exception_pro = new Exception(Tip.PortIllegal);
                    return false;
                }
                if (!MailSp.isMail(mailInfo.senderAddress_pro))
                {
                    exception_pro = new Exception(Tip.SenderIllegal);
                    return false;
                }
                return true;
            }
            #endregion
    
            #region isServerReady Function
            public bool isServerReady()
            {
                string back = receive();
                return back.Substring(0, 3).Equals(SMTP_BACKS.SERVER_READY_OK);//Response code from server always is 3 byte length.
            }
            #endregion
    
            #region verify Function
            public bool verify()
            {
                socketSend(SMTP_CMD.VERIFY);
                string[] verifyBacks = receive().Split(new string[] { "
    " }, StringSplitOptions.RemoveEmptyEntries);
                for (int index = 0; index < verifyBacks.Length; index++)
                {
                    string verifyBack = verifyBacks[index];
                    if (verifyBack.Length <= 3)
                    {
                        return false;
                    }
    
                    if (!verifyBack.Substring(0, 3).Equals(SMTP_BACKS.OPERATE_COMPLETE))
                    {
                        return false;
                    }
                }
                return true;
            }
            #endregion
    
            #region authLogin function
            private bool authLogin()
            {
                socketSend(SMTP_CMD.AUTH_LOGIN);
                string authLoginBack = receive();
                if (string.IsNullOrEmpty(authLoginBack) || authLoginBack.Length <= 3)
                {
                    return false;
                }
                return authLoginBack.Substring(0, 3).Equals(SMTP_BACKS.AUTH_LOGIN_OK);
            }
            #endregion
    
            #region userNameLogin function
            private bool userNameLogin(string userName)
            {
                if (string.IsNullOrEmpty(userName))
                {
                    return false;
                }
                string base64UserName = Base64Sp.tobase64Str(userName);
                socketSend(base64UserName + "
    ");
                string userNameLoginBack = receive();
                if (string.IsNullOrEmpty(userNameLoginBack) || userNameLoginBack.Length <= 3)
                {
                    return false;
                }
                return userNameLoginBack.Substring(0, 3).Equals(SMTP_BACKS.USER_NAME_LOGIN_OK);
            }
    
    
            #endregion
    
            #region passowrdLogin function
            private bool passowrdLogin(string password)
            {
                if (string.IsNullOrEmpty(password))
                {
                    return false;
                }
                socketSend(Base64Sp.tobase64Str(password) + "
    ");
                string passowrdLoginBack = receive();
                if (string.IsNullOrEmpty(passowrdLoginBack) || passowrdLoginBack.Length <= 3)
                {
                    return false;
                }
                return passowrdLoginBack.Substring(0, 3).Equals(SMTP_BACKS.PASSWORD_LOGIN_OK);
            }
    
    
            #endregion
    
            #region mailFrom function
            private bool mailFrom(string senderAddress)
            {
                socketSend(SMTP_CMD.MAIL_FROM + "<" + senderAddress + ">
    ");
                string mailFromBack = receive();
                if (string.IsNullOrEmpty(mailFromBack) || mailFromBack.Length <= 3)
                {
                    return false;
                }
                return mailFromBack.Substring(0, 3).Equals(SMTP_BACKS.OPERATE_COMPLETE);
            }
            #endregion
    
            #region rcptTo function
            private bool rcptTo(List<string> receiverAddresses)
            {
                foreach (string receiverAddress in receiverAddresses)
                {
                    socketSend(SMTP_CMD.RCPT_TO + "<" + receiverAddress + ">
    ");
                    string rcptBack = receive();
                    if (string.IsNullOrEmpty(rcptBack) || rcptBack.Length <= 3)
                    {
                        return false;
                    }
    
                    if (!rcptBack.Substring(0, 3).Equals(SMTP_BACKS.OPERATE_COMPLETE))
                    {
                        return false;
                    }
                }
                return true;
            }
            #endregion
    
            #endregion
    
            #region send mail body functions
            private bool sendMail(MailInfo mailInfo)
            {
                socketSend(SMTP_CMD.SEND_BODY);
                string back = receive();
                if (string.IsNullOrEmpty(back) || back.Length <= 3)
                {
                    return false;
                }
    
                if (!back.Substring(0, 3).Equals(SMTP_BACKS.DATA_OK))
                {
                    return false;
                }
    
                sendMailHeader(mailInfo);
                sendMailContent(mailInfo.content_pro);
                sendMailAttachment(mailInfo.attachments_pro);
                sendMailTail();
    
                back = receive();
                if (string.IsNullOrEmpty(back) || back.Length <= 3)
                {
                    return false;
                }
    
                if (!back.Substring(0, 3).Equals(SMTP_BACKS.OPERATE_COMPLETE))
                {
                    return false;
                }
    
                return true;
            }
    
            private void sendMailAttachment(List<string> attachments)
            {
                foreach (string attachment in attachments)//Add header per attachment.
                {
                    if (!File.Exists(attachment))
                    {
                        continue;
                    }
                    sendAttachmentHeader(attachment);
                    sendAttachmentData(attachment);
                }
            }
    
            private void sendAttachmentData(string attachment)
            {
                byte[] attachmentData = FileSp.readFileBytes(attachment);
                socketSend(Convert.ToBase64String(attachmentData));
                socketSend("
    
    ");
            }
    
            private void sendAttachmentHeader(string attachment)
            {
                string contentType = "application/octet-stream";//Easy to transmission more format file;
                string header = "--" + boundary_pro + "
    "
                        + "Content-Type:"+contentType+";name=" + attachment + "
    "
                        + "Content-Transfer-Encoding:base64
    "
                        + "Content-Disposition:attachment;filename="" + attachment + ""
    ";
                socketSend(header + "
    ");
            }
    
            private void sendMailTail()
            {
                socketSend("
    .
    ");//. is content end flag.        
            }
    
            private void sendMailHeader(MailInfo mailInfo)
            {
                string to = "";
                foreach (string receiverAddress in mailInfo.receiverAddresses_pro)
                {
                    to += "To:" + receiverAddress + "
    ";
                }
    
                //if you want to hide receiver,may assign to="To:abc@a.com
    ";
                //string to = "To:abc@a.com
    ";
                socketSend(to);
    
    
                string from = "From:" + mailInfo.senderAddress_pro + "
    ";
                socketSend(from);
    
               //Avoid subject messy code,adopt encoding header statement.
                string subject = "Subject:=?" + encoding_subject_pro.BodyName + "?B?"
                                + Base64Sp.tobase64Str(mailInfo.subject_pro, Encoding.UTF8) + "?=
    ";
                socketSend(subject);
                string header = "Mime-Version:1.0
    "
                          + "Content-type:multipart/mixed;"
                          + "boundary="" + boundary_pro + "";
    "//define content type and boundary value.
                          + "Content-Transfer-Encoding:7bit
    "
                          + "This is a multi-part message in MIME format
    ";
                socketSend(header + "
    ");
            }
    
            private void sendMailContent(string content)
            {
                sendContentHeader();
                sendContentBody(content);
            }
    
            private void sendContentBody(string content)
            {
                //If content is too long,need split some blocks and send.
                //Length of one line is always 80 byte.
                string newContent = Base64Sp.tobase64Str(content, encoding_content_pro);
                socketSend(newContent + "
    ");
            }
    
            private void sendContentHeader()
            {
                string header = "--" + boundary_pro + "
    "//boundary must begin --
                     + "Content-type:text/plain;charset=" + encoding_content_pro.BodyName + "
    "//Avoid messy code,add charset statement.
                     + "Content-Transfer-Encoding:base64
    "//Avoid messy code,use encoding base64.
                socketSend(header + "
    ");
            }
    
            #endregion
    
    
            private class Tip//Easy to change other language tip.
            {
                public static string AuthLoginFail = "Auth login fail!";
                public static string ConnectFail = "Connect mail host fail!";
                public static string IpIllegal = "Ip is illegal!";
                public static string MailFromFail = "Input sender address fail!";
                public static string PasswordLoginFail = "Password login fail!";
                public static string PortIllegal = "Port is illegal!";
                public static string ReceiveInfoEmpty = "Receive info is empty!";
                public static string RcptToFail = "Input receiver address fail!";
                public static string SenderIllegal = "Sender mail address is illegal!";
                public static string SendMailFail = "Send mail fail!";
                public static string ServerReadyFail = "Server ready fail!";
                public static string UserNameLoginFail = "User name login fail!";
                public static string VerifyFail = "Verify identity fail!";
            }
        }
    }
    


    具体工程可以到 http://download.csdn.net/detail/xxdddail/5802901下载

  • 相关阅读:
    HTML基础
    JVM内存和JVM调优(五)--分代垃圾回收详述
    JVM内存和JVM调优(四)--如何区分垃圾
    JVM内存和JVM调优(三)--基本GC垃圾回收算法
    JVM内存和JVM调优(二)--引用类型
    JVM内存和JVM调优(一)--堆栈概念
    isAssignableFrom和instanceof
    spring学习(三十九)--自定义注解
    SPRING学习(三十八)--SPRING集成MYBATIS之数据库连接池和多种数据源配置方式(三)
    SPRING学习(三十七)--SPRING集成MYBATIS(二)
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3211955.html
Copyright © 2020-2023  润新知