프로그래밍/ASP.NET
C# SMTP 대량메일 보내기
쇠주는참이슬
2012. 10. 23. 10:01
출처 : Code Snipet
C# SMTP로 대량 메일 발송하기.
Soket 이용
It’s easy to use System.net.mail namespace to send emails from asp.net. But the problem is system.net.mail.send() method does not close the connection to SMTP server. This is causing SMTP 4.2.2 error if you try to send multiple emails. While as per Microsoft this issue has been resolved in .net Framework 4.0 but people who are using 3.5 its still the issue. The workaround is to use sockets and System.Web.Mail namespace. Here is the sample code to send SMTP email using C# 3.5 -
workaround may be set maxtimeout=1
.NET Framework 4.0 has new property called SMTPClient.Dispose() to fix the issue
004 | using System.Net.Sockets; |
006 | using System.Web.Mail; |
011 | /// provides methods to send email via smtp direct to mail server |
013 | public class SmtpDirect |
016 | /// Get / Set the name of the SMTP mail server |
018 | private static string SmtpServer = "outbound-mail.yourorg.com"; |
019 | private enum SMTPResponse : int |
021 | CONNECT_SUCCESS = 220, |
022 | GENERIC_SUCCESS = 250, |
026 | public static bool Send(MailMessage message) |
028 | IPHostEntry IPhst = Dns.Resolve(SmtpServer); |
029 | IPEndPoint endPt = new IPEndPoint(IPhst.AddressList[0], 25); |
030 | Socket s = new Socket(endPt.AddressFamily, SocketType.Stream, ProtocolType.Tcp); |
033 | if (!Check_Response(s, SMTPResponse.CONNECT_SUCCESS)) |
039 | Senddata(s, string.Format("HELO {0}\r\n", Dns.GetHostName())); |
040 | if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS)) |
046 | Senddata(s, string.Format("MAIL From: {0}\r\n", message.From)); |
047 | if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS)) |
054 | string _To = message.To; |
055 | string[] Tos = _To.Split(new char[] { ';' }); |
056 | foreach (string To in Tos) |
058 | Senddata(s, string.Format("RCPT TO: {0}\r\n", To)); |
059 | if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS)) |
066 | if (message.Cc != null) |
068 | Tos = message.Cc.Split(new char[] { ';' }); |
069 | foreach (string To in Tos) |
071 | Senddata(s, string.Format("RCPT TO: {0}\r\n", To)); |
072 | if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS)) |
080 | StringBuilder Header = new StringBuilder(); |
081 | Header.Append("From: " + message.From + "\r\n"); |
082 | Tos = message.To.Split(new char[] { ';' }); |
083 | Header.Append("To: "); |
084 | for (int i = 0; i < Tos.Length; i++) |
086 | Header.Append(i > 0 ? "," : ""); |
087 | Header.Append(Tos[i]); |
089 | Header.Append("\r\n"); |
090 | if (message.Cc != null) |
092 | Tos = message.Cc.Split(new char[] { ';' }); |
093 | Header.Append("Cc: "); |
094 | for (int i = 0; i < Tos.Length; i++) |
096 | Header.Append(i > 0 ? "," : ""); |
097 | Header.Append(Tos[i]); |
099 | Header.Append("\r\n"); |
101 | Header.Append("Date: "); |
102 | Header.Append(DateTime.Now.ToString("ddd, d M y H:m:s z")); |
103 | Header.Append("\r\n"); |
104 | Header.Append("Subject: " + message.Subject + "\r\n"); |
105 | Header.Append("X-Mailer: SMTPDirect v1\r\n"); |
106 | string MsgBody = message.Body; |
107 | if (!MsgBody.EndsWith("\r\n")) |
109 | if (message.Attachments.Count > 0) |
111 | Header.Append("MIME-Version: 1.0\r\n"); |
112 | Header.Append("Content-Type: multipart/mixed; boundary=unique-boundary-1\r\n"); |
113 | Header.Append("\r\n"); |
114 | Header.Append("This is a multi-part message in MIME format.\r\n"); |
115 | StringBuilder sb = new StringBuilder(); |
116 | sb.Append("--unique-boundary-1\r\n"); |
117 | sb.Append("Content-Type: text/plain\r\n"); |
118 | sb.Append("Content-Transfer-Encoding: 7Bit\r\n"); |
120 | sb.Append(MsgBody + "\r\n"); |
123 | foreach (object o in message.Attachments) |
125 | MailAttachment a = o as MailAttachment; |
129 | FileInfo f = new FileInfo(a.Filename); |
130 | sb.Append("--unique-boundary-1\r\n"); |
131 | sb.Append("Content-Type: application/octet-stream; file=" + f.Name + "\r\n"); |
132 | sb.Append("Content-Transfer-Encoding: base64\r\n"); |
133 | sb.Append("Content-Disposition: attachment; filename=" + f.Name + "\r\n"); |
135 | FileStream fs = f.OpenRead(); |
136 | binaryData = new Byte[fs.Length]; |
137 | long bytesRead = fs.Read(binaryData, 0, (int)fs.Length); |
139 | string base64String = System.Convert.ToBase64String(binaryData, 0, binaryData.Length); |
141 | for (int i = 0; i < base64String.Length; ) |
144 | if (base64String.Length - (i + nextchunk) < 0) |
145 | nextchunk = base64String.Length - i; |
146 | sb.Append(base64String.Substring(i, nextchunk)); |
153 | MsgBody = sb.ToString(); |
156 | Senddata(s, ("DATA\r\n")); |
157 | if (!Check_Response(s, SMTPResponse.DATA_SUCCESS)) |
162 | Header.Append("\r\n"); |
163 | Header.Append(MsgBody); |
164 | Header.Append(".\r\n"); |
165 | Header.Append("\r\n"); |
166 | Header.Append("\r\n"); |
167 | Senddata(s, Header.ToString()); |
168 | if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS)) |
174 | Senddata(s, "QUIT\r\n"); |
175 | Check_Response(s, SMTPResponse.QUIT_SUCCESS); |
179 | private static void Senddata(Socket s, string msg) |
181 | byte[] _msg = Encoding.ASCII.GetBytes(msg); |
182 | s.Send(_msg, 0, _msg.Length, SocketFlags.None); |
184 | private static bool Check_Response(Socket s, SMTPResponse response_expected) |
188 | byte[] bytes = new byte[1024]; |
189 | while (s.Available == 0) |
191 | System.Threading.Thread.Sleep(100); |
194 | s.Receive(bytes, 0, s.Available, SocketFlags.None); |
195 | sResponse = Encoding.ASCII.GetString(bytes); |
196 | response = Convert.ToInt32(sResponse.Substring(0, 3)); |
197 | if (response != (int)response_expected) |
Usage
1 | string sBody = string.Empty; |
2 | System.Web.Mail.MailMessage message = new System.Web.Mail.MailMessage(); |
3 | message.From = "def@hotmail.com"; |
4 | message.To="abc@yahoo.com"; |
5 | message.Subject = "Hello subject"; |