Lumisoft.NET 에 깊이 들 어가 메 일 발송 기능 을 실현 하 는 방법 에 대한 상세 한 설명

앞의 일부 글 에서 DotNet 에 SMTP 류 의 메 일 발송 기능 이 내장 되 어 있 고 첨부 파일,이미지 삽입 모델 이 모두 소개 되 어 있 습 니 다.본 고 는 Lumisoft.NET 이라는 매우 우수한 오픈 소스 구성 요 소 를 계속 소개 하고 이 구성 요소 로 메 일 도 구 를 디자인 개발 하면 더욱 편리 하고 기능 이 더욱 강해 집 니 다.인터넷 의 많은 글 들 은 기본적으로 이 구성 요 소 를 사용 하여 메 일 을 받 는 방법 을 소개 하고 이 구성 요 소 를 사용 하여 메 일 발송 기능 을 하 는 것 을 적 게 소개 한다.본 고 는 주로 이 구성 요 소 를 이용 하여 메 일의 발송 기능 을 탐색 하고 자 한다.메 일 발송 은 두 가지 방식 이 있 는데 하 나 는 보 낸 사람 없 이 메 일 을 보 낼 수 있 는 것 이 고 하 나 는 보 낸 사람 계 정 비밀번호 와 SMTP 서버 를 이용 하여 메 일 발송 을 실현 하 는 것 이다.본 고 는 이 두 가지 방식 에 대해 소개 하고 자 한다.
구성 요소 다운로드 주소:http://www.lumisoft.ee/lswww/download/downloads/ 
구성 요소 포럼 주소:http://www.lumisoft.ee/Forum/default.aspx?g=forum 
일 관 된 방법 을 계승 하여 먼저 관련 실현 도형 을 붙 이 고 감각 적 인 인식 에서 상세 한 소개 설명 에 들 어가 가장 좋 은 이해 깊이 를 얻 도록 한다.
1.먼저 보 내 는 사람의 설정 입 니 다.텍스트 파일 내 보 내기,새로 만 들 기 등 작업 을 통 해 사용자 가 조작 할 수 있 습 니 다. 
 2.내용 도 가 져 오기 와 내 보 내기 를 지원 하고 데이터베이스 에 저장 하여 기록 과 조작 등 을 편리 하 게 할 수 있 습 니 다.또한 내용 을 무 작위 로 헷 갈 리 게 할 수 있 습 니 다.헷 갈 리 는 내용 은 HTML 메 일 에 숨겨 져 있어 서버 의 식별 을 헷 갈 리 게 할 수 있 습 니 다
3.메 일 발송 은 두 가지 방식 을 선택 할 수 있 습 니 다.다음은 이 두 가지 방식 의 실현 을 소개 할 것 입 니 다.하 나 는 이 컨트롤 을 사용 하여 아주 좋 은 메 일 직접 투자 기술 을 사용 하고 SMTP 계 정 으로 보 내지 않 아 도 됩 니 다.하 나 는 일반적인 SMTP 발송 방식 이다.물론 우 리 는 메 일 끝부분 정보,HTML 내용 알림,그리고 발송 기간 에 자동 으로 전 화 를 걸 수 있 는 설정 작업 등 더 많은 인 자 를 설정 할 수 있다4.메 일 직 투 기술 은 아 날로 그 계 정 을 통 해 사용자 의 메 일 주 소 를 추가 하거나 위장 할 수 있 습 니 다.그 중에서 저 는 자주 사용 하 는 SMTP 서버 의 도 메 인 이름 을 작 성 했 습 니 다.그 중에서 요구 에 맞 는 메 일 형식 을 구성 하 는 데 편리 하고 메 일 영수증 알림 도 설정 할 수 있 습 니 다.다음 그림 과 같 습 니 다. 
  5.일반 발송 방식 을 사용한다 면 사용자 의 계 정 비밀번호 등 정 보 를 작성 하고 발송 할 때 자동 으로 발송 자 정 보 를 받 아 대량으로 발송 해 야 합 니 다마지막 으로 소량의 메 일의 발송 효 과 를 체험 하고 발송 은 다 중 스 레 드 로 보 냅 니 다.다 중 스 레 드 는 비교적 유명한 SmartThreadPool 구성 요 소 를 사용 하고 발송 과정 은 그 중의 로 그 를 상세 하 게 기록 하 므 로 참고 하 시기 바 랍 니 다.

관련 기능 효과 도 를 소개 하고 다음 에 주요 기능 이 실 현 된 코드 를 분석 하 겠 습 니 다

private TimerHelper timer = null;

        private void btnSend_Click(object sender, EventArgs e)
        {
            //
            failedItems = 0;
            successItems = 0;

            workItemsCompleted = 0;
            workItemsGenerated = 0;

            Portal.gc.FailedCount = 0;//

            STPStartInfo stpStartInfo = new STPStartInfo();
            stpStartInfo.IdleTimeout = 10;
            stpStartInfo.MaxWorkerThreads = 100;
            stpStartInfo.MinWorkerThreads = 0;
            //stpStartInfo.StartSuspended = true;
            _smartThreadPool = new SmartThreadPool(stpStartInfo);
            _workItemsGroup = _smartThreadPool;

            workItemsProducerThread = new Thread(new ThreadStart(this.WorkItemsProducer));
            workItemsProducerThread.IsBackground = true;
            workItemsProducerThread.Start();

            RefreshStatusCount();

            int intervalRedial = SystemConfig.Default.IntervalRedial * 1000 * 60;
            if (intervalRedial > 0)
            {
                if (timer != null)
                {
                    timer.Stop();
                    timer.Dispose();
                }
                timer = new TimerHelper(intervalRedial,false);
                timer.Execute += new TimerHelper.TimerExecution(timer_Execute);
                timer.Start();
            }
        }

        private static object locker = new object();
        private void timer_Execute()
        {
            if (Monitor.TryEnter(locker))
            {
                string message = string.Format(" {0} !", DateTime.Now);
                ShowSendStatus(message);

                string RasName = SystemConfig.Default.RasName;
                if (!string.IsNullOrEmpty(RasName))
                {
                    message = string.Format(" ({0})", RasName);
                    ShowSendStatus(message);

                    Portal.gc.ReConnect(RasName);
                    Portal.gc.FailedCount = 0;//
                }

                Monitor.Exit(locker);
            }
            else
            {
                Monitor.Enter(locker);
                Monitor.Exit(locker);
            }
        }

위 는 주요 임무 생 성 작업 과 관련 된 전화 걸 기 작업 입 니 다.그 중에서 임무 의 상세 한 생 성 코드 는 다음 과 같 습 니 다.private void WorkItems Producer()

{
            CallCtrlWithThreadSafetyEx.SetText(this.txtSendDetail, "");

            EnableControl(false, true, true);
            string message = string.Format(" ");
            RecordMessage(message);

            #region

            IWorkItemsGroup workItemsGroup = _workItemsGroup;
            if (null == workItemsGroup)
            {
                return;
            }

            List<string> addressList = GetAddressList();
            List<MyMailInfo> mailInfoList = GetMailInfo();
            for (int i = 0; i < addressList.Count; i++)
            {
                try
                {
                    SendJobInfo jobInfo = new SendJobInfo();
                    jobInfo.domainList = mailDomainList;
                    jobInfo.mailTo = addressList[i];
                    jobInfo.mailInfo = GetOneMail(mailInfoList, i);
                    jobInfo.ShowSendStatus = ShowSendStatus;
                    jobInfo.currentDomain = (i % mailDomainList.Count);// ,
                    jobInfo.UseDirectSendType = SystemConfig.Default.EmailDirectSend;

                    // ,
                    // , ,
                    if (string.IsNullOrEmpty(SystemConfig.Default.UserEmailFrom))
                    {
                        jobInfo.mailFromDisplay = SystemConfig.Default.DefaultFromDisplayName;
                    }

                    workItemCallback = new WorkItemCallback(this.DoWork);
                    workItemsGroup.QueueWorkItem(workItemCallback, jobInfo);
                    Thread.Sleep(100);
                }
                catch (ObjectDisposedException ex)
                {
                    LogTextHelper.WriteLine(ex.ToString());
                    continue;
                }

                Interlocked.Increment(ref workItemsGenerated);
            }

            #endregion

            RefreshStatusCount();
            message = string.Format(" {0} , {1} ",
                workItemsGenerated, workItemsGenerated - workItemsCompleted);
            CallCtrlWithThreadSafetyEx.SetText(this, message);
            RecordMessage(message);

            try
            {
                //workItemsGroup.Start();
                workItemsGroup.WaitForIdle();
                _smartThreadPool.Shutdown();
            }
            catch (Exception ex)
            {
                LogTextHelper.WriteLine(ex.ToString());
            }

            UpdateFinishStatus();
        }

다 중 스 레 드 로 처리 되 었 기 때문에 발송 을 중단 할 때 관련 스 레 드 대상 을 방출 해 야 합 니 다.다음 코드 와 같 습 니 다

private void btnStop_Click(object sender, EventArgs e)
        {
            try
            {
                _smartThreadPool.Shutdown();
                _smartThreadPool.Dispose();
                _smartThreadPool = null;

                if (timer != null)
                {
                    timer.Stop();
                    timer.Dispose();
                }
            }
            catch (Exception ex)
            {
                LogTextHelper.WriteLine(ex.ToString());
            }

            UpdateFinishStatus();
        }

그 중에서 구체 적 인 메 일 발송 기능 은 SendJobInfo 에 봉 하여 서로 다른 유형 을 판단 하여 서로 다른 발송 작업 을 한다.
그 중에서 가장 관건 적 인 발송 코드 는 LumiSoft.NET 구성 요 소 를 어떻게 이용 하여 해당 하 는 메 일 대상 을 구성 하 는 지 하 는 것 입 니 다.다음은 메 일 직 투 의 발송 방식 을 먼저 소개 하 겠 습 니 다.이 구성 요소 의 포장 이 비교적 좋 기 때문에 직 투 발송 방식 은 매우 간단 합 니 다

Mail_Message message = Create_PlainText_Html_Attachment_Image(mailTo, mailFrom, mailFromDisplay);
SMTP_Client.QuickSend(message);
그 중에서 CreatePlainText_Html_Attachment_Image 의 패 키 징 함수 의 상세 한 내용 은 다음 과 같다

       private Mail_Message Create_PlainText_Html_Attachment_Image(string mailTo, string mailFrom, string mailFromDisplay)
        {
            Mail_Message msg = new Mail_Message();
            msg.MimeVersion = "1.0";
            msg.MessageID = MIME_Utils.CreateMessageID();
            msg.Date = DateTime.Now;
            msg.From = new Mail_t_MailboxList();
            msg.From.Add(new Mail_t_Mailbox(mailFromDisplay, mailFrom));
            msg.To = new Mail_t_AddressList();
            msg.To.Add(new Mail_t_Mailbox(mailTo, mailTo));
            msg.Subject = mailInfo.Title;

            //
            string notifyEmail = SystemConfig.Default.DispositionNotificationTo;
            if (!string.IsNullOrEmpty(notifyEmail) && ValidateUtil.IsEmail(notifyEmail))
            {
                msg.DispositionNotificationTo = new Mail_t_Mailbox(notifyEmail, notifyEmail);
            }

            #region MyRegion
            //--- multipart/mixed -----------------------------------
            MIME_h_ContentType contentType_multipartMixed = new MIME_h_ContentType(MIME_MediaTypes.Multipart.mixed);
            contentType_multipartMixed.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.');
            MIME_b_MultipartMixed multipartMixed = new MIME_b_MultipartMixed(contentType_multipartMixed);
            msg.Body = multipartMixed;

            //--- multipart/alternative -----------------------------
            MIME_Entity entity_multipartAlternative = new MIME_Entity();
            MIME_h_ContentType contentType_multipartAlternative = new MIME_h_ContentType(MIME_MediaTypes.Multipart.alternative);
            contentType_multipartAlternative.Param_Boundary = Guid.NewGuid().ToString().Replace('-', '.');
            MIME_b_MultipartAlternative multipartAlternative = new MIME_b_MultipartAlternative(contentType_multipartAlternative);
            entity_multipartAlternative.Body = multipartAlternative;
            multipartMixed.BodyParts.Add(entity_multipartAlternative);

            //--- text/plain ----------------------------------------
            MIME_Entity entity_text_plain = new MIME_Entity();
            MIME_b_Text text_plain = new MIME_b_Text(MIME_MediaTypes.Text.plain);
            entity_text_plain.Body = text_plain;

            // , HTML,
            string plainTextBody = " HTML , “ ” , ";
            if (!string.IsNullOrEmpty(SystemConfig.Default.PlaintTextTips))
            {
                plainTextBody = SystemConfig.Default.PlaintTextTips;
            }

            text_plain.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, plainTextBody);
            multipartAlternative.BodyParts.Add(entity_text_plain);

            //--- text/html -----------------------------------------
            string htmlText = mailInfo.Content;//"<html> ,<img src=\"cid:test.jpg\"> <font color=red><b>LumiSoft.Net</b></font></html>";
            MIME_Entity entity_text_html = new MIME_Entity();
            MIME_b_Text text_html = new MIME_b_Text(MIME_MediaTypes.Text.html);
            entity_text_html.Body = text_html;
            text_html.SetText(MIME_TransferEncodings.QuotedPrintable, Encoding.UTF8, htmlText);
            multipartAlternative.BodyParts.Add(entity_text_html);

            //--- application/octet-stream -------------------------
            foreach (string attach in mailInfo.Attachments)
            {
                multipartMixed.BodyParts.Add(Mail_Message.CreateAttachment(attach));
            }

            foreach (string imageFile in mailInfo.EmbedImages)
            {
                MIME_Entity entity_image = new MIME_Entity();
                entity_image.ContentDisposition = new MIME_h_ContentDisposition(MIME_DispositionTypes.Inline);
                string fileName = DirectoryUtil.GetFileName(imageFile, true);
                entity_image.ContentID = BytesTools.BytesToHex(Encoding.Default.GetBytes(fileName));               
                MIME_b_Image body_image = new MIME_b_Image(MIME_MediaTypes.Image.jpeg);
                entity_image.Body = body_image;
                body_image.SetDataFromFile(imageFile, MIME_TransferEncodings.Base64);
                multipartMixed.BodyParts.Add(entity_image);
            }

            #endregion

            return msg;
        }

일반적인 계 정 방식 으로 SMTP 메 일 을 보 내 면 주요 코드 는 다음 과 같다.그 중에서 명령 방식 을 이용 하여 서버 와 한 걸음 한 걸음 상호작용 을 하 는 것 을 알 수 있다

using (SMTP_Client client = new SMTP_Client())
                    {
                        int port = domainInfo.Ssl ? WellKnownPorts.SMTP_SSL : WellKnownPorts.SMTP;
                        if (domainInfo.Port > 0)
                        {
                            port = domainInfo.Port;
                        }

                        client.Connect(domainInfo.SmtpServer, port, domainInfo.Ssl);
                        client.Authenticate(domainInfo.Username, domainInfo.Password);
                        //string text = client.GreetingText;
                        client.MailFrom(mailFrom, -1);
                        client.RcptTo(mailTo);

                        MemoryStream stream = Create_Html_Attachment_Image(mailTo, mailFrom, mailFromDisplay);
                        client.SendMessage(stream);
                        client.Disconnect();
                    }

그 중에서 메 일 내용 을 구성 하 는 코드 는 아까 의 부분 과 유사 하고 상세 한 코드 는 다음 과 같다

private MemoryStream Create_Html_Attachment_Image(string mailTo, string mailFrom, string mailFromDisplay)
        {
            Mime m = new Mime();
            MimeEntity mainEntity = m.MainEntity;

            mainEntity.From = new AddressList();
            mainEntity.From.Add(new MailboxAddress(mailFromDisplay, mailFrom));

            mainEntity.To = new AddressList();
            mainEntity.To.Add(new MailboxAddress(mailTo, mailTo));
            mainEntity.Subject = mailInfo.Title;
            mainEntity.ContentType = MediaType_enum.Multipart_mixed;

            MimeEntity textEntity = mainEntity.ChildEntities.Add();
            textEntity.ContentType = MediaType_enum.Text_html;
            textEntity.ContentTransferEncoding = ContentTransferEncoding_enum.QuotedPrintable;
            textEntity.DataText = mailInfo.Content;
.........................        

        MemoryStream msg = new MemoryStream();
            m.ToStream(msg);
            msg.Position = 0;

            return msg;
        }

Lumisoft.NET 이라는 구성 요 소 를 이용 하면 관련 메 일 작업 을 많이 실현 할 수 있 습 니 다.여 기 는 관심 과 지면 원인 에 중심 을 두 고 메 일 발송 기능 모듈 을 소개 합 니 다.그 중에서 붙 인 코드 는 관심 이 있 는 친구 와 서로 교류 하기 위해 서 입 니 다.하 나 는 앞으로 자신 이 참고 하기 위해 서 입 니 다.이 소프트웨어 나 코드 로 스 팸 메 일 을 대량으로 보 내 는 것 을 장려 하지 않 는 다.

좋은 웹페이지 즐겨찾기