Chương 5: Giao Tiếp Với Email


1. Giới Thiệu

Email (thư điện tử) là phương thức giao tiếp phổ biến và quan trọng nhất trong môi trường Internet. Lập trình quản lý email cho phép ứng dụng tự động gửi thông báo, nhận và xử lý thư — đây là kỹ năng thiết yếu trong phát triển phần mềm hiện đại.


2. Email Là Gì?

Mỗi địa chỉ email có dạng:

<Username>@<domain name>

Trong đó:

  • <domain name>: phải duy nhất toàn cầu trên hệ thống DNS
  • <Username>: chỉ cần duy nhất trong mail server của người nhận

Ví dụ: hiendo@teacher.nt106


3. Nguyên Tắc Hoạt Động Gửi/Nhận Mail

sequenceDiagram participant UA as User Agent (Client) participant S1 as Mail Server (Người gửi) participant S2 as Mail Server (Người nhận) participant UA2 as User Agent (Client nhận) UA->>S1: Gửi email (SMTP) S1->>S2: Chuyển tiếp email (SMTP) UA2->>S2: Lấy email (POP3 / IMAP / HTTP)
  • Gửi email: Dùng giao thức SMTP
  • Nhận email: Dùng POP3 (port 110) hoặc IMAP (port 143)
  • Webmail: Dùng giao thức HTTP (Gmail, Outlook Web…)

4. Email Clients và Webmail

WebmailEmail Client
Truy cập quaTrình duyệt webỨng dụng cài đặt (Outlook, Thunderbird…)
Ví dụGmail, Yahoo MailMicrosoft Outlook, MDaemon
Giao thứcHTTP/HTTPSSMTP, POP3, IMAP

5. SMTP – Simple Mail Transfer Protocol

5.1 Đặc điểm

  • Là giao thức chỉ dùng để gửi email
  • Mọi mail server đều phải tuân theo chuẩn SMTP
  • Dùng TCP port 25
  • Có thể kiểm tra bằng telnet

5.2 Phiên làm việc SMTP

sequenceDiagram participant C as Client (Telnet) participant S as SMTP Server S-->>C: 220 mail.teacher.nt106 ESMTP (chào hỏi) C->>S: EHLO teacher.nt106 S-->>C: 250 Hello ... pleased to meet you C->>S: AUTH LOGIN S-->>C: 334 (yêu cầu username base64) C->>S: [username base64] S-->>C: 334 (yêu cầu password base64) C->>S: [password base64] S-->>C: 235 Authentication successful C->>S: MAIL FROM: S-->>C: 250 Sender OK C->>S: RCPT TO: S-->>C: 250 Recipient OK C->>S: DATA S-->>C: 354 Enter mail, end with . C->>S: To: hiendo@teacher.nt106 C->>S: From: lando@teacher.nt106 C->>S: Subject: Test C->>S: [nội dung thư] C->>S: . S-->>C: 250 Ok, message saved C->>S: QUIT S-->>C: 221 See ya

5.3 Cấu trúc một email (RFC 822)

To: hiendo@teacher.nt106
From: lando@teacher.nt106
Subject: Test mail
                          ← dòng trống phân cách header và body
Hello, This is a test mail from Telnet.
Goodbye.

6. Lập Trình Gửi Mail

6.1 Dùng TcpClient (giao tiếp SMTP thủ công)

Đây là cách giao tiếp trực tiếp với SMTP server ở mức socket, giúp hiểu rõ giao thức.

Khai báo thư viện:

using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO;

Kết nối đến SMTP server:

TcpClient tcpClient = new TcpClient();
tcpClient.Connect("127.0.0.1", 25);

Đọc/ghi dữ liệu qua stream:

StreamReader sr = new StreamReader(tcpClient.GetStream());
StreamWriter sw = new StreamWriter(tcpClient.GetStream());

Hàm mã hóa Base64 (SMTP yêu cầu username/password dạng Base64):

static public string EncodeTo64(string toEncode)
{
    byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
    string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
    return returnValue;
}

Toàn bộ luồng gửi mail:

// 1. Chào server
sw.WriteLine("EHLO teacher.nt106"); sw.Flush();

// 2. Chọn xác thực
sw.WriteLine("AUTH LOGIN"); sw.Flush();

// 3. Gửi username và password (base64)
sw.WriteLine(EncodeTo64(mailfrom)); sw.Flush();
sw.WriteLine(EncodeTo64(password)); sw.Flush();

// 4. Gửi địa chỉ người gửi và người nhận
sw.WriteLine("MAIL FROM:<" + mailfrom + ">"); sw.Flush();
sw.WriteLine("RCPT TO:<" + mailto + ">"); sw.Flush();

// 5. Bắt đầu nội dung
sw.WriteLine("DATA"); sw.Flush();
sw.WriteLine("Subject: " + subject); sw.Flush();
sw.WriteLine("From: " + mailfrom); sw.Flush();
sw.WriteLine("To: " + mailto); sw.Flush();
sw.WriteLine(""); // dòng trống
sw.WriteLine(body); sw.Flush();
sw.WriteLine("."); sw.Flush(); // kết thúc nội dung

// 6. Ngắt kết nối
sw.WriteLine("QUIT"); sw.Flush();

6.2 Dùng SmtpClient (thư viện .NET tích hợp)

Cách này đơn giản hơn nhiều, .NET lo phần giao thức:

private void sendEmail_Click(object sender, EventArgs e)
{
    using (SmtpClient smtpClient = new SmtpClient("127.0.0.1"))
    {
        string mailfrom = txtMailFrom.Text.Trim();
        string mailto   = txtMailTo.Text.Trim();
        string password = txtPass.Text.Trim();

        var basicCredential = new NetworkCredential(mailfrom, password);

        using (MailMessage message = new MailMessage())
        {
            smtpClient.UseDefaultCredentials = false;
            smtpClient.Credentials = basicCredential;

            message.From    = new MailAddress(mailfrom);
            message.Subject = txtSubject.Text.Trim() + " From SMTPClient";
            message.IsBodyHtml = true;  // cho phép gửi HTML
            message.Body   = rtbBody.Text;
            message.To.Add(mailto);

            try
            {
                smtpClient.Send(message);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}

6.3 Dùng MailKit (khuyến nghị cho dự án thực tế)

https://github.com/jstedfast/MailKit

MailKit hỗ trợ SMTP, POP3, IMAP đầy đủ, hỗ trợ TLS/SSL, OAuth2, và nhiều tính năng hiện đại khác.


7. POP3 – Post Office Protocol

7.1 Lịch sử và đặc điểm

  • Ra đời năm 1984 do hạn chế tốc độ và băng thông lúc bấy giờ
  • POP2 ra đời năm 1985
  • POP3 là chuẩn phổ biến nhất hiện nay, định nghĩa trong RFC 1939, hoạt động trên TCP port 110
  • Hỗ trợ tùy chọn “leave mail on server” (giữ lại thư trên server)

7.2 Luồng hoạt động POP3

flowchart TD A[Kết nối TCP đến server port 110] --> B[Xác thực USER/PASS] B --> C[Nhận toàn bộ email về máy local] C --> D[Lưu cục bộ như mail mới] D --> E[Xóa mail trên server] E --> F[Ngắt kết nối]

7.3 Các lệnh POP3 quan trọng

LệnhMô tả
USER <username>Gửi tên đăng nhập
PASS <password>Gửi mật khẩu
STATXem trạng thái mailbox → +OK <số thư> <dung lượng>
RETR <n>Lấy email thứ n
DELE <n>Đánh dấu xóa email thứ n (chưa xóa ngay)
RSETHủy tất cả đánh dấu xóa
QUITKết thúc phiên, xóa thật các mail đã DELE

8. IMAP – Internet Message Access Protocol

8.1 Đặc điểm

  • Ra đời năm 1986, định nghĩa trong RFC 1730, chạy trên TCP port 143
  • Ý tưởng cốt lõi: cho phép người dùng xem email từ nhiều thiết bị khác nhau
  • Email lưu trên server, không tải hết về máy
  • Hỗ trợ flags (đánh dấu đã đọc, đã trả lời, đã chuyển tiếp…)

8.2 Luồng hoạt động IMAP

flowchart TD A[Kết nối TCP đến server port 143] --> B[Xác thực LOGIN] B --> C[Lấy nội dung được yêu cầu, lưu đệm local] C --> D[Xử lý thao tác người dùng: đọc, đánh dấu, xóa...] D --> E[Ngắt kết nối]

8.3 Các lệnh IMAP quan trọng

a1 LOGIN <username> <password>
   → OK LOGIN completed

a2 LIST "" "*"
   → Liệt kê tất cả folder (INBOX, Sent, Drafts...)

a3 EXAMINE INBOX
   → Xem thông tin hộp thư đến (số thư, flags...)

a4 FETCH <n> BODY[]
   → Lấy nội dung email thứ n

a5 STORE <n> +FLAGS \Deleted
   → Đánh dấu xóa email thứ n

a6 LOGOUT
   → Đăng xuất

9. So Sánh POP3 và IMAP

Chọn POP3 khi:

  • Chỉ dùng email trên một thiết bị duy nhất
  • Cần đọc email khi không có Internet
  • Dung lượng lưu trữ trên server hạn chế

Chọn IMAP khi:

  • Dùng email trên nhiều thiết bị (PC, điện thoại, laptop…)
  • Có kết nối Internet ổn định
  • Muốn xem nhanh mail mới mà không tải hết về
  • Dung lượng máy local hạn chế
  • Cần sao lưu/dự phòng dữ liệu trên server

10. Câu Hỏi Ôn Tập