Maison >développement back-end >Golang >Comment Golang implémente la fonction de transfert de courrier SMTP
Golang, en tant que langage de programmation puissant, fonctionne particulièrement bien dans le domaine de la programmation réseau. Lors de la communication sur le réseau, Golang fournit de nombreux outils et bibliothèques pratiques, dont la bibliothèque SMTP. En tant que protocole de transmission réseau, le protocole SMTP est utilisé pour envoyer et recevoir des e-mails et constitue un élément important de la communication réseau. Dans les applications pratiques, il est parfois nécessaire de transférer les e-mails reçus. Cet article présentera comment Golang implémente la fonction de transfert d'e-mails SMTP.
SMTP (Simple Mail Transfer Protocol) est un protocole de transfert de courrier basé sur du texte utilisé pour envoyer et recevoir des e-mails. Le protocole SMTP est l'un des protocoles standards d'Internet et constitue le protocole principal pour l'envoi d'e-mails. Le protocole SMTP utilise TCP comme protocole de transmission sous-jacent et le port 25 comme port de transmission.
SMTP contient les concepts de base suivants :
Le workflow du protocole SMTP est le suivant :
En utilisant la bibliothèque SMTP de Golang, vous pouvez facilement envoyer des e-mails. La bibliothèque SMTP de Golang implémente la fonction d'envoi d'e-mails basée sur le protocole SMTP et fournit une interface API pratique.
Tout d'abord, vous devez utiliser la fonction Dial fournie dans la bibliothèque SMTP pour vous connecter au serveur SMTP. Cette fonction doit transmettre l'adresse et le numéro de port du serveur SMTP, le nom d'utilisateur et le mot de passe ainsi que d'autres informations.
func Dial(addr string, a Auth) (*Client, error)
Parmi eux, le type Auth représente les informations d'authentification du serveur SMTP, y compris le nom d'utilisateur et le mot de passe. L'exemple de code pour se connecter au serveur SMTP est le suivant :
import (
"net/smtp"
)
func main() {
// 创建认证信息 auth := smtp.PlainAuth("", "smtp_username", "smtp_password", "smtp_host") // 连接SMTP服务器 client, err := smtp.Dial("smtp_host:smtp_port") if err != nil { panic(err) } // 登录SMTP服务器 err = client.Auth(auth) if err != nil { panic(err) } // 退出SMTP服务器 defer client.Quit()
}
Après vous être connecté avec succès au serveur SMTP, vous pouvez envoyer des informations par e-mail au serveur selon les exigences du protocole SMTP. Vous devez utiliser les méthodes Mail et Rcpt fournies par la bibliothèque smtp pour envoyer les informations sur l'expéditeur et le destinataire. Les exemples de codes pour les méthodes Mail et Rcpt sont les suivants :
//Envoyer les informations sur l'expéditeur
func (c *Client) Erreur Mail (à partir de la chaîne)
//Envoyer les informations sur le destinataire
func (c *Client) Rcpt( à string) erreur
Pour envoyer des informations par e-mail, vous devez utiliser la méthode Data fournie par la bibliothèque smtp pour envoyer le contenu de l'e-mail au serveur SMTP. L'exemple de code de la méthode Data est le suivant :
//Envoyer le contenu de l'e-mail
func (c *Client) Data() (io.WriteCloser, erreur)
Après l'envoi de l'e-mail, vous devez fermer la connexion et utiliser la méthode Quit pour quitter le serveur SMTP. Le code est le suivant :
// Quitter le serveur SMTP
func (c *Client) Erreur Quit()
Afin d'implémenter la fonction de redirection d'e-mail, une fois l'e-mail envoyé reçu, le contenu de l'e-mail doit être transmis au destinataire désigné. Par conséquent, vous devez utiliser la bibliothèque SMTP de Golang pour envoyer le contenu de l'e-mail au serveur SMTP et au destinataire spécifiés.
Les étapes spécifiques sont les suivantes :
Le code d'implémentation spécifique est le suivant :
import (
"bytes" "errors" "fmt" "log" "net" "net/smtp" "strings"
)
//Port d'écoute
func ListenAndServe(addr string) erreur {
listener, err := net.Listen("tcp", addr) if err != nil { return err } defer listener.Close() for { conn, err := listener.Accept() if err != nil { log.Printf("Failed to accept connection (%s)", err) continue } go handleConnection(conn) }
}
//Traitement des e-mails reçus
func handleConnection(conn net .Conn) {
defer conn.Close() // 读取邮件内容 buf := make([]byte, 4096) n, err := conn.Read(buf) if err != nil { log.Printf("Failed to read connection (%s)", err) return } defer conn.Close() // 解析邮件 message, err := parseMessage(buf[:n]) if err != nil { log.Printf("Failed to parse message (%s)", err) return } // 判断收件人和发件人是否符合要求 if !checkRecipient(message.Recipient) { log.Printf("Invalid recipient (%s)", message.Recipient) return } if !checkSender(message.Sender) { log.Printf("Invalid sender (%s)", message.Sender) return } // 构建SMTP客户端 auth := smtp.PlainAuth("", "smtp_username", "smtp_password", "smtp_host") client, err := smtp.Dial("smtp_host:smtp_port") if err != nil { log.Printf("Failed to connect SMTP server (%s)", err) return } defer client.Quit() // 发送邮件内容 err = client.Mail("from_address") if err != nil { log.Printf("Failed to send 'MAIL FROM' command (%s)", err) return } err = client.Rcpt(message.Recipient) if err != nil { log.Printf("Failed to send 'RCPT TO' command (%s)", err) return } w, err := client.Data() if err != nil { log.Printf("Failed to send 'DATA' command (%s)", err) return } defer w.Close() buf.WriteString(fmt.Sprintf("To: %s\r\n", message.Recipient)) buf.WriteString(fmt.Sprintf("From: %s\r\n", message.Sender)) buf.WriteString(fmt.Sprintf("Subject: %s\r\n", message.Subject)) buf.WriteString("\r\n") buf.WriteString(message.Body) _, err = w.Write(buf.Bytes()) if err != nil { log.Printf("Failed to write email to client (%s)", err) return } log.Printf("Mail sent to %s", message.Recipient)
}
// Analyser le contenu de l'e-mail
func parseMessage(message []byte) (*Message, erreur) {
var msg Message msg.Body = string(message) // 提取发件人地址 start := bytes.Index(message, []byte("From: ")) if start == -1 { return nil, errors.New("Failed to find 'From:' in message") } start += 6 end := bytes.Index(message[start:], []byte("\r\n")) if end == -1 { return nil, errors.New("Failed to find end of 'From:' in message") } msg.Sender = string(message[start : start+end]) // 提取收件人地址 start = bytes.Index(message, []byte("To: ")) if start == -1 { return nil, errors.New("Failed to find 'To:' in message") } start += 4 end = bytes.Index(message[start:], []byte("\r\n")) if end == -1 { return nil, errors.New("Failed to find end of 'To:' in message") } msg.Recipient = string(message[start : start+end]) // 提取邮件主题 start = bytes.Index(message, []byte("Subject: ")) if start == -1 { return nil, errors.New("Failed to find 'Subject:' in message") } start += 9 end = bytes.Index(message[start:], []byte("\r\n")) if end == -1 { return nil, errors.New("Failed to find end of 'Subject:' in message") } msg.Subject = string(message[start : start+end]) return &msg, nil
}
// Vérifier si le destinataire est légitime
func checkRecipient (chaîne du destinataire) bool {
// 收件人地址必须以@mydomain.com结尾 return strings.HasSuffix(recipient, "@mydomain.com")
}
// Vérifiez si l'expéditeur est légitime
func checkSender(chaîne de l'expéditeur) bool {
// 任意发件人地址均合法 return true
}
// Structure de l'e-mail
type Structure du message {
Sender string Recipient string Subject string Body string
}
Grâce à la bibliothèque SMTP de Golang, nous pouvons facilement implémenter la fonction d'envoi et de transfert d'e-mails. Lors de la mise en œuvre du transfert d'e-mails SMTP, vous devez prêter attention à la vérification du destinataire et de l'expéditeur pour garantir la sécurité du contenu de l'e-mail. Dans des applications pratiques, la fonction de transfert d'e-mails SMTP peut être appliquée à divers scénarios, tels que le transfert d'e-mails internes au sein de l'entreprise, le transfert de messages sur les réseaux sociaux, etc.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!