Rumah > Artikel > pembangunan bahagian belakang > Bagaimana untuk melaksanakan pelayan e-mel mudah menggunakan golang
Dengan perkembangan dan pempopularan Internet, e-mel telah menjadi bahagian yang sangat diperlukan dalam kehidupan orang ramai. Artikel ini akan memperkenalkan cara menggunakan bahasa pengaturcaraan golang untuk melaksanakan pelayan e-mel yang mudah.
1. Persediaan persekitaran
Pertama sekali, anda perlu menyediakan persekitaran pembangunan golang secara tempatan. Selepas memasang golang, anda perlu menetapkan GOPATH Pembolehubah persekitaran ini menentukan direktori kerja golang Semua fail yang dibuat dalam direktori ini dianggap sebagai kod sumber golang.
Seterusnya, pasang perpustakaan POP3 dan SMTP melalui arahan berikut:
go get github.com/jordan-wright/email go get github.com/beego/mux
Dua perpustakaan di atas digunakan untuk menghantar e-mel dan mengendalikan permintaan HTTP masing-masing.
2. Laksanakan pelayan POP3
POP3 ialah protokol penerimaan mel boleh dimuat turun daripada pelayan mel menggunakan protokol POP3. Untuk melaksanakan pelayan POP3, kita perlu menulis pelayan TCP dalam golang. Dalam golang, anda boleh menggunakan pakej "bersih" untuk melaksanakan pembangunan pelayan TCP.
Berikut ialah kod pelayan POP3 yang ringkas:
package main import ( "bufio" "fmt" "net" "strings" ) func handlePOP3(conn net.Conn) { fmt.Fprintf(conn, "+OK POP3 ready\r\n") scanner := bufio.NewScanner(conn) for scanner.Scan() { command := scanner.Text() if strings.HasPrefix(command, "QUIT") { fmt.Fprintf(conn, "+OK Bye\r\n") conn.Close() return } fmt.Fprintf(conn, "-ERR unknown command\r\n") } } func main() { listener, err := net.Listen("tcp", ":110") if err != nil { fmt.Println("Error listening:", err.Error()) return } defer listener.Close() fmt.Println("Listening on :110") for { conn, err := listener.Accept() if err != nil { fmt.Println("Error accepting connection:", err.Error()) return } go handlePOP3(conn) } }
Kod di atas mendengar secara setempat kepada port 110 (port lalai POP3 apabila pelanggan menyambung, goroutine mula mengendalikannya). . Semua arahan yang diterima oleh pelayan POP3 adalah rentetan, jadi kami menggunakan Pengimbas yang disediakan oleh pakej bufio untuk menghuraikan arahan.
Dalam fungsi handlePOP3, kami mula-mula menghantar "+OK POP3 ready" kepada klien untuk menunjukkan bahawa pelayan sudah sedia. Kemudian, ia terus membaca arahan yang dihantar oleh klien dalam gelung Jika ia menemui arahan "QUIT", ia menghantar "+OK Bye" untuk menamatkan sesi dan menutup sambungan. Jika arahan lain yang tidak diketahui diterima, hantarkan "-ERR unknown command" untuk memberitahu klien bahawa arahan itu tidak sah.
3. Laksanakan pelayan SMTP
SMTP ialah protokol penghantaran mel boleh dihantar ke pelayan mel menggunakan protokol SMTP. Untuk melaksanakan pelayan SMTP, kami perlu menambah beberapa kod berdasarkan pelayan POP3 untuk memproses arahan SMTP.
Berikut ialah kod pelayan SMTP yang ringkas:
package main import ( "fmt" "net" "net/mail" "net/smtp" ) func handlePOP3(conn net.Conn) { // ... } func handleSMTP(conn net.Conn) { fmt.Fprintf(conn, "220 localhost SMTP Ready\r\n") state := 0 var from, to, data string for { buf := make([]byte, 1024) _, err := conn.Read(buf) if err != nil { fmt.Println("Error reading:", err.Error()) return } line := string(buf) switch state { case 0: if line[:4] != "HELO" { fmt.Fprintf(conn, "500 Error: bad command sequence\r\n") continue } fmt.Fprintf(conn, "250 localhost\r\n") state = 1 case 1: if line[:4] != "MAIL" { fmt.Fprintf(conn, "500 Error: bad command sequence\r\n") continue } from = line[5 : len(line)-2] fmt.Fprintf(conn, "250 OK\r\n") state = 2 case 2: if line[:4] != "RCPT" { fmt.Fprintf(conn, "500 Error: bad command sequence\r\n") continue } to = line[5 : len(line)-2] fmt.Fprintf(conn, "250 OK\r\n") state = 3 case 3: if line[:4] == "DATA" { fmt.Fprintf(conn, "354 End data with <CR><LF>.<CR><LF>\r\n") state = 4 } else if line[:4] == "HELO" { fmt.Fprintf(conn, "250 localhost\r\n") } else { fmt.Fprintf(conn, "500 Error: bad command sequence\r\n") } case 4: if line[:3] == "QUIT" { fmt.Fprintf(conn, "221 Bye\r\n") conn.Close() return } if line == ".\r\n" { fmt.Fprintf(conn, "250 OK: message accepted\r\n") msg, _ := mail.ReadMessage(strings.NewReader(data)) smtp.SendMail("localhost:25", nil, "test@test.com", []string{to}, []byte(data)) state = 1 } else { data += line } } } } func main() { // ... router := mux.NewRouter() router.HandleFunc("/pop3", handlePOP3) router.HandleFunc("/smtp", handleSMTP) http.ListenAndServe(":8080", router) }
Kod di atas mendengar secara setempat pada port 25 (port lalai SMTP apabila pelanggan menyambung, goroutine mula mengendalikannya). . Semua arahan yang diterima oleh pelayan SMTP juga adalah rentetan, jadi kami menggunakan kaedah Conn.Read yang disediakan oleh pakej bersih untuk membaca arahan.
Dalam fungsi handleSMTP, kami mula-mula menghantar "220 localhost SMTP Ready" kepada klien untuk menunjukkan bahawa pelayan SMTP sudah sedia. Kemudian, kekalkan mesin keadaan untuk mengendalikan proses penghantaran mel:
Jika arahan tidak sah diterima, hantar "500 Ralat: urutan arahan buruk" memberitahu pelanggan bahawa arahan itu tidak sah. Jika arahan QUIT diterima, "221 Bye" dihantar untuk menunjukkan tamat sesi dan sambungan ditutup. Dalam Negeri 4, kami menggunakan pakej net/mel untuk menghuraikan data e-mel dan pakej net/smtp untuk menghantar e-mel.
4. Pengujian
Pelayan peti mel yang dilaksanakan menggunakan kod di atas hanyalah contoh mudah Jika ia hendak digunakan dalam persekitaran pengeluaran sebenar, banyak aspek ujian dan pengoptimuman diperlukan. Berikut ialah kod klien SMTP ringkas yang ditulis dalam python Anda boleh menggunakan klien ini untuk menghantar e-mel ke pelayan SMTP kami dan menguji sama ada pelayan SMTP berfungsi dengan betul:
import smtplib server = smtplib.SMTP('localhost', 25) server.ehlo() server.mail('test@test.com') server.rcpt('test1@test.com') server.data('Subject: Test Mail\n\nThis is a test email.\n') server.quit()
Ringkasan
Artikel ini memperkenalkan cara melaksanakan pelayan e-mel mudah menggunakan bahasa pengaturcaraan golang. Menggunakan golang untuk menulis kod pelayan SMTP/POP3 mudah difahami dan dikembangkan Pada masa yang sama, ciri coroutine golang boleh menyokong konkurensi tinggi dan sangat sesuai untuk kerja pembangunan pengaturcaraan rangkaian.
Atas ialah kandungan terperinci Bagaimana untuk melaksanakan pelayan e-mel mudah menggunakan golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!