> 백엔드 개발 > Golang > Golang이 SMTP 메일 전달 기능을 구현하는 방법

Golang이 SMTP 메일 전달 기능을 구현하는 방법

PHPz
풀어 주다: 2023-04-25 10:38:01
원래의
1252명이 탐색했습니다.

Golang은 강력한 프로그래밍 언어로서 네트워크 프로그래밍 분야에서 특히 뛰어난 성능을 발휘합니다. 네트워크를 통해 통신할 때 Golang은 많은 편리한 도구와 라이브러리를 제공하며 그 중 하나가 SMTP 라이브러리입니다. 네트워크 전송 프로토콜인 SMTP 프로토콜은 이메일을 보내고 받는 데 사용되며 네트워크 통신의 중요한 부분입니다. 실제 애플리케이션에서는 수신된 이메일을 전달해야 하는 경우가 있습니다. 이 기사에서는 Golang이 SMTP 이메일 전달 기능을 구현하는 방법을 소개합니다.

  1. SMTP 소개

SMTP(Simple Mail Transfer Protocol)는 이메일을 보내고 받는 데 사용되는 텍스트 기반 메일 전송 프로토콜입니다. SMTP 프로토콜은 인터넷 표준 프로토콜 중 하나이며 이메일 전송의 핵심 프로토콜입니다. SMTP 프로토콜은 기본 전송 프로토콜로 TCP를 사용하고 전송 포트로 포트 25를 사용합니다.

SMTP에는 다음과 같은 기본 개념이 포함되어 있습니다.

  • 메일 보낸 사람: 메일을 보내야 하는 사용자 또는 시스템입니다.
  • 메일 수신자: 메일을 받아야 하는 사용자 또는 시스템입니다.
  • SMTP 클라이언트: 메일 전송을 위한 애플리케이션입니다.
  • SMTP 서버: 이메일 수신 및 전달을 위한 서버입니다.

SMTP 프로토콜 작업 흐름은 다음과 같습니다.

  • 클라이언트가 SMTP 서버에 연결됩니다.
  • 클라이언트는 통신 매개변수를 협상하기 위해 EHLO 명령을 서버에 보냅니다.
  • 클라이언트는 인증 정보를 서버로 보냅니다.
  • 클라이언트는 이메일 정보와 수신자 정보를 서버로 보냅니다.
  • 서버는 수신자 정보를 기반으로 수신 서버를 찾아 연결합니다.
  • 이메일 정보와 수신자 정보를 수신 서버로 보냅니다.
  • 수신 서버는 이메일을 해당 메일함에 저장합니다.
  1. SMTP 라이브러리 사용

Golang의 SMTP 라이브러리를 사용하면 쉽게 이메일을 보낼 수 있습니다. Golang의 SMTP 라이브러리는 SMTP 프로토콜을 기반으로 이메일 전송 기능을 구현하고 편리한 API 인터페이스를 제공합니다.

먼저 SMTP 서버에 접속하기 위해서는 SMTP 라이브러리에서 제공하는 Dial 기능을 이용해야 합니다. 이 기능은 SMTP 서버의 주소와 포트 번호, 사용자 이름과 비밀번호, 기타 정보를 전달해야 합니다.

func Dial(addr string, a Auth) (*클라이언트, 오류)

이 중 Auth 유형은 사용자 이름과 비밀번호를 포함한 SMTP 서버의 인증 정보를 나타냅니다. SMTP 서버에 연결하기 위한 샘플 코드는 다음과 같습니다.

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()
로그인 후 복사

}

SMTP 서버에 성공적으로 연결한 후 서버에 이메일 정보를 보낼 수 있습니다. SMTP 프로토콜의 요구 사항에 따라. 보낸 사람과 받는 사람 정보를 보내려면 smtp 라이브러리에서 제공하는 Mail 및 Rcpt 메서드를 사용해야 합니다. Mail 및 Rcpt 메소드의 샘플 코드는 다음과 같습니다.

//발신자 정보 보내기
func (c *Client) Mail(from string) error

//수신자 정보 보내기
func (c *Client) Rcpt( to string) error

이메일 정보를 보내려면 smtp 라이브러리에서 제공하는 Data 메소드를 사용하여 이메일 내용을 SMTP 서버로 보내야 합니다. Data 메소드의 샘플 코드는 다음과 같습니다.

//Send email content
func (c *Client) Data() (io.WriteCloser, error)

이메일을 보낸 후에는 연결을 닫고 사용해야 합니다. SMTP 서버를 종료하는 Quit 메소드. 코드는 다음과 같습니다.

// SMTP 서버 종료
func (c *Client) Quit() 오류

  1. 이메일 전달 기능 구현

이메일 전달 기능을 구현하려면 이메일을 보낸 후 이메일 내용을 지정된 수신자에게 전달해야 합니다. 따라서 지정된 SMTP 서버와 수신자에게 이메일 콘텐츠를 보내려면 Golang의 SMTP 라이브러리를 사용해야 합니다.

구체적인 단계는 다음과 같습니다.

  • 프로젝트의 포트 번호를 듣고 수신 이메일을 수락하세요.
  • 수신자와 발신자가 요구 사항을 충족하는지 확인하세요. 일치하는 경우 이메일 내용이 메일 유형으로 캡슐화되어 전달 서비스 주소로 전송됩니다.
  • 포워딩 서비스로부터 응답을 받아 이메일이 성공적으로 전달되었는지 확인하세요.

구체적인 구현 코드는 다음과 같습니다.

import (

"bytes"
"errors"
"fmt"
"log"
"net"
"net/smtp"
"strings"
로그인 후 복사

)

// Listening port
func ListenAndServe(addr string) error {

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)
}
로그인 후 복사

}

// 수신된 이메일 처리
func handlerConnection(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)
로그인 후 복사

}

// 이메일 내용 구문 분석
func parseMessage(message []byte) (*Message, error) {

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
로그인 후 복사

}

// 수신자가 합법적인지 확인
func checkRecipient (수신자 문자열) bool {

// 收件人地址必须以@mydomain.com结尾
return strings.HasSuffix(recipient, "@mydomain.com")
로그인 후 복사

}

// 보낸 사람이 합법적인지 확인
func checkSender(sender string) bool {

// 任意发件人地址均合法
return true
로그인 후 복사

}

// 이메일 구조
type 메시지 구조 {

Sender    string
Recipient string
Subject   string
Body      string
로그인 후 복사

}

  1. 결론

Golang의 SMTP 라이브러리를 통해 이메일의 전송 및 전달 기능을 쉽게 구현할 수 있습니다. SMTP 이메일 전달을 구현할 때 이메일 내용의 보안을 보장하기 위해 수신자와 발신자 확인에 주의해야 합니다. 실제 애플리케이션에서 SMTP 이메일 전달 기능은 기업 내부 이메일 전달, 소셜 네트워크에서의 메시지 전달 등과 같은 다양한 시나리오에 적용될 수 있습니다.

위 내용은 Golang이 SMTP 메일 전달 기능을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿