golang編寫SMTP郵箱服務端

來源:互聯網
上載者:User
package mainimport (    "fmt"    "net"    "os")type Mail struct {    clientName string    from       string    to         string    data       string    reciveData bool}func main() {    listen, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("127.0.0.1"), 25, ""})    if err != nil {        fmt.Println("監聽連接埠失敗:", err.Error())        return    }    defer listen.Close()    recive(listen)}func recive(listen *net.TCPListener) {    for {        conn, err := listen.AcceptTCP() //接收串連        defer conn.Close()        if err != nil {            fmt.Println("用戶端串連異常", err.Error()) //用戶端串連異常            continue        }        conn.Write([]byte("220 GoMailSever "))        fmt.Println("新用戶端", conn.RemoteAddr().String())        go func() {            tmpBuffer := make([]byte, 0)           //建立待處理位元組切片            readerChannel := make(chan []byte, 16) //建立channel通訊管道            _mail := &Mail{}            go reader(readerChannel, conn, _mail) //channel資訊接收端            data := make([]byte, 1024)            //建立輸出緩衝切片            for {                i, err := conn.Read(data) //從Socket讀取資料                if err != nil {                    fmt.Println("讀取發生錯誤", err.Error()) //讀取失敗發生錯誤                    return                }                tmpBuffer = DepackMail(append(tmpBuffer, data[:i]...), readerChannel) //用自訂協議處理位元組                //fmt.Println(data, string(data))            }        }()    }}func reader(readerChannel chan []byte, conn *net.TCPConn, _mail *Mail) {    for {        select {        case data := <-readerChannel:            fmt.Println(string(data[0:4]))            switch string(data[0:4]) {            case "HELO":                _mail.clientName = string(data[4+2:])                conn.Write([]byte("250 Give Me Mail"))                break            case "MAIL":                _mail.from = string(data[4+2:])                conn.Write([]byte("250 Give I am fine"))                break            case "RCPT":                _mail.to = string(data[4+2:])                conn.Write([]byte("250 Give I am fine"))                break            case "DATA":                conn.Write([]byte("354 Give I am fine"))                break            case "QUIT":                conn.Write([]byte("221 ByeBye"))                file, _ := os.Create("./mail/3.eml")                file.WriteString(_mail.data)                file.Close()                fmt.Println(_mail)                break            default:                _mail.data = _mail.data + string(data)                fmt.Println(string(_mail.data[len(_mail.data)-1:]))                if string(_mail.data[len(_mail.data)-1:]) == "." {                    fmt.Println("111")                    conn.Write([]byte("250 Give I am fine"))                }                break            }        }    }}func DepackMail(buffer []byte, readerChannel chan []byte) []byte {    length := len(buffer)    var i int    for i = 0; i < length; {        if length < i+4 { //2位為尾標記            break        }        var sIndex int        for dump := i; dump < length-1; dump++ {            if buffer[dump] == byte(13) && buffer[dump+1] == byte(10) {                sIndex = dump            }        }        if sIndex <= 0 {            break        }        data := buffer[i:sIndex]        readerChannel <- data //向管道發送資料        i = sIndex + 2    }    if i == length { //全部處理完畢返回空包        return make([]byte, 0)    }    return buffer[i:] //未處理完畢返回 剩餘包}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.