Go语言实现SMTP服务器欢迎消息获取与关键词校验
获取SMTP服务器欢迎消息并检查关键词的完整实现
看起来你想要实现连接SMTP服务器后,先获取它的欢迎消息并检查是否包含特定关键词,同时还写了一部分LOGIN认证的代码对吧?我帮你把这段代码补全,并且加上完整的欢迎消息检查逻辑。
首先整理并补全你给出的未完成代码,再整合欢迎消息的获取与检查功能:
package main import ( "bufio" "errors" "fmt" "net" "net/smtp" "strings" "time" ) type loginAuth struct { username, password string } func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) { return "LOGIN", []byte{}, nil } func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) { if more { switch strings.TrimSpace(string(fromServer)) { case "Username:": return []byte(a.username), nil case "Password:": return []byte(a.password), nil default: return nil, errors.New("unexpected server challenge") } } return nil, nil } // 获取SMTP欢迎消息并检查指定关键词 func checkSMTPWelcomeMsg(serverAddr string, keyword string) (string, error) { // 建立TCP连接,设置5秒超时 conn, err := net.DialTimeout("tcp", serverAddr, 5*time.Second) if err != nil { return "", fmt.Errorf("连接失败: %w", err) } defer conn.Close() // 设置读取超时,避免长时间阻塞 err = conn.SetReadDeadline(time.Now().Add(5 * time.Second)) if err != nil { return "", fmt.Errorf("设置读取超时失败: %w", err) } // 读取SMTP服务器发送的第一条消息(欢迎消息,以220开头) scanner := bufio.NewScanner(conn) if !scanner.Scan() { return "", fmt.Errorf("未收到欢迎消息: %w", scanner.Err()) } welcomeMsg := scanner.Text() // 验证是否为合法的SMTP欢迎消息 if !strings.HasPrefix(welcomeMsg, "220") { return welcomeMsg, fmt.Errorf("无效的SMTP欢迎消息") } // 检查关键词是否存在(大小写不敏感) if !strings.Contains(strings.ToLower(welcomeMsg), strings.ToLower(keyword)) { return welcomeMsg, fmt.Errorf("欢迎消息中未找到关键词 '%s'", keyword) } return welcomeMsg, nil } func main() { // 替换为你的SMTP服务器地址 serverAddr := "smtp.example.com:25" // 替换为你要检查的关键词 targetKeyword := "example" // 先执行欢迎消息检查 welcomeMsg, err := checkSMTPWelcomeMsg(serverAddr, targetKeyword) if err != nil { fmt.Printf("错误: %v\n", err) return } fmt.Printf("收到欢迎消息: %s\n", welcomeMsg) fmt.Printf("关键词 '%s' 已找到!\n", targetKeyword) // 如果需要继续进行SMTP操作(比如发邮件),可以创建SMTP客户端 client, err := smtp.Dial(serverAddr) if err != nil { fmt.Printf("创建SMTP客户端失败: %v\n", err) return } defer client.Quit() // 使用LOGIN认证 auth := &loginAuth{username: "你的用户名", password: "你的密码"} err = client.Auth(auth) if err != nil { fmt.Printf("认证失败: %v\n", err) return } // 后续可添加发邮件逻辑,比如设置发件人、收件人等 // client.Mail("sender@example.com") // client.Rcpt("recipient@example.com") // ... }
关键细节说明:
- 欢迎消息获取:标准库的
smtp.Dial会自动读取欢迎消息但不会返回,所以这里用net.DialTimeout手动建立TCP连接,直接读取服务器发送的第一行内容,也就是SMTP欢迎消息。 - 关键词检查:采用了大小写不敏感的匹配逻辑,你可以根据需求修改为严格大小写匹配。
- LOGIN认证补全:补全了你未完成的
Next方法,处理了服务器对用户名和密码的提示,同时增加了意外挑战的错误处理。 - 超时设置:给连接和读取操作都添加了超时限制,避免程序无意义阻塞。
如果你只需要检查欢迎消息,直接调用checkSMTPWelcomeMsg函数即可;如果还要进行发邮件等后续操作,可以基于示例中的SMTP客户端继续开发。
内容的提问来源于stack exchange,提问作者kingcope
相关产品推荐
相关产品推荐

