Maison >développement back-end >Golang >Comment Golang implémente la fonction de transfert de courrier SMTP

Comment Golang implémente la fonction de transfert de courrier SMTP

PHPz
PHPzoriginal
2023-04-25 10:33:191259parcourir

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.

  1. Introduction à 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 :

  • Expéditeur de courrier : l'utilisateur ou le système qui doit envoyer du courrier.
  • Destinataire du courrier : l'utilisateur ou le système qui doit recevoir du courrier.
  • Client SMTP : Application d'envoi de mails.
  • Serveur SMTP : Serveur de réception et de transfert d'e-mails.

Le workflow du protocole SMTP est le suivant :

  • Le client se connecte au serveur SMTP.
  • Le client envoie la commande EHLO au serveur pour négocier les paramètres de communication.
  • Le client envoie les informations d'authentification au serveur.
  • Le client envoie des informations sur l'e-mail et les informations sur le destinataire au serveur.
  • Le serveur trouve et se connecte au serveur de réception en fonction des informations du destinataire.
  • Envoyez les informations de courrier électronique et les informations sur le destinataire au serveur de réception.
  • Le serveur de réception stocke l'e-mail dans la boîte aux lettres correspondante.
  1. Utilisation de la bibliothèque SMTP

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()

  1. Implémentation de la fonction de redirection d'e-mail

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 :

  • Écoutez le numéro de port dans le projet et acceptez les e-mails entrants.
  • Déterminez si le destinataire et l'expéditeur répondent aux exigences. S'il correspond, le contenu de l'e-mail est encapsulé dans le type de courrier et envoyé à l'adresse du service de transfert.
  • Recevez la réponse du service de transfert et déterminez si l'e-mail a été transféré avec succès.

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

}

  1. Conclusion

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn