使用 SMTP 协议发送邮件问题求教,我自己是真解决不了

2025 年 5 月 19 日
 tiRolin

现在有要求如下

websocket 连接/smtp 端点,模拟 SMTP 协议发送邮件,发件地址: test@mine.com ,收件地址 test@nullht.com ,邮件内容 Hello World 。请注意:大小写敏感,websocket 连接仅保留 1 分钟左右,断了需要重连并重头发送 SMTP 命令

可以确定发送的地址是 wss://interview-test.nullht.com/smtp

我按照他的要求,写出了下面的代码,其他的不重要,我们直接看我发送请求的格式

    private void initializeCommands() {
        commandQueue.clear();
        commandQueue.add("EHLO mine.com\r\n");
        commandQueue.add("MAIL FROM:<test@mine.com>\r\n");
        commandQueue.add("RCPT TO:<test@nullht.com>\r\n");
        commandQueue.add("DATA\r\n");
        // 注意:邮件内容需要包含完整格式
        commandQueue.add(
            "From: test@mine.com\r\n" +
                "To: test@nullht.com\r\n" +
                "Subject: Hello\r\n" +
                "\r\n" +  // 空行分隔头部和正文
                "Hello World\r\n" +
                ".\r\n"    // 结束符
        );
        commandQueue.add("QUIT\r\n");
    }

这个代码可以得到下面的响应:

Sending command: EHLO mine.com
Server response: 220 邮件服务器准备就绪
Server response: 250 很高兴认识你
Sending command: MAIL FROM:<test@mine.com>
Server response: 250 发件人已接受
Sending command: RCPT TO:<test@nullht.com>
Server response: 250 收件人已接受
Sending command: DATA
Server response: 500 命令不被识别

显然是 DATA 后的内容有问题,其他的都没毛病。但是我参照下面的教程

https://blog.csdn.net/weixin_39833509/article/details/88965720

感觉这个格式也没问题啊,我试了好久了都没搞出来到底哪里有问题,什么 AI 、谷歌全试过了,有没有大佬救一下,小弟我是真不行了,我先谢谢各位了

5541 次点击
所在节点    Java
26 条回复
lemonda
2025 年 5 月 19 日
不懂,但是以前排查过一个收不到信的情况,看看 DATA 的邮件模板是 CRLF 还是 LF
phrack
2025 年 5 月 19 日
这也太底层了,email 的协议又很古老复杂,现在不都是用第三方发信直接 rest api 就完了,第三方帮你屏蔽了底层细节了。
poxiaogg
2025 年 5 月 19 日
不需要\r\n 结尾
```
commandQueue.add("DATA");
```
ysc3839
2025 年 5 月 19 日
bingfengfeifei
2025 年 5 月 19 日
看了下 Suricata 解析 smtp 的代码,看上去没问题啊 说不定是服务器实现有问题
tiRolin
2025 年 5 月 19 日
@bingfengfeifei 服务器不太可能有问题,因为这个服务器不是我的,而是公司提供的
ZiLong
2025 年 5 月 19 日
捞服务器日志看下,有可能错的是服务器实现呢
hefish
2025 年 5 月 19 日
\r\n 改成 \n\r 看看。。
这个协议会话没问题。 我 20 年前搞邮件服务器时候,手动 telnet 25 测试发信也是这么输入的。
gesse
2025 年 5 月 20 日
是不是先要验证——执行“AUTH LOGIN\r\n”命令?
daxy223
2025 年 5 月 20 日
yinmin
2025 年 5 月 20 日
用 gpt 或 claude 写一个 websocket to tcp 的桥接程序,还原出 smtp ,然后用 java 内置的发邮件功能试试。

自己手搓基于邮件协议的代码,中文编码、html 邮件、附件功能都是有工作量的。
yinmin
2025 年 5 月 20 日
你可以问问公司是否能提供 smtp ( 25 端口)或者 smtps ( 465 端口),可以直接用 java 内置的发邮件功能;或者是否提供高级的邮件 api ,输入 from 、to 、subject 、mailbody 能直接发邮件。

基于 smtp 协议让员工手搓,感觉有点扯了。
jason56
2025 年 5 月 20 日
估计是服务端需要验证,试试 AUTH LOGIN / USER /PASS
gtese
2025 年 5 月 20 日
去问下服务器是不是支持匿名,看看匿名怎么写, 如果是需要验证,再去找下验证怎么写。
smtp 出故障的时候,用 telnet 一条条命令试。试成了再去用代码。
hytex
2025 年 5 月 20 日
这个已经玩过了,直接给你发结果
import asyncio
import websockets

async def send_smtp_commands():
uri = "wss://interview-test.nullht.com/smtp" # 根据实际情况修改为 wss:// 或 ws://

try:
async with websockets.connect(uri) as websocket:
# 等待服务器欢迎语(类似于 220 开头的回应)
print(await websocket.recv())

# 按照 SMTP 协议逐步发送命令
await websocket.send("HELO localhost")
print(await websocket.recv())

await websocket.send("MAIL FROM:<test@mine.com>")
print(await websocket.recv())

await websocket.send("RCPT TO:<test@nullht.com>")
print(await websocket.recv())

await websocket.send("DATA")
print(await websocket.recv())

await websocket.send("Hello World")
# print(await websocket.recv())


await websocket.send(".")
print(await websocket.recv())


await websocket.send("QUIT")
print(await websocket.recv())

except Exception as e:
print(f"连接或发送失败: {e}")

asyncio.run(send_smtp_commands())
hytex
2025 年 5 月 20 日
@hytex 自己格式化一下 0.0
lucasdev
2025 年 5 月 20 日
宇宙的终极最终答案:42
是因为这个服务器“只识别单行命令的,要一行行发送,包括最后的.” 参考 https://linux.do/t/topic/638484/24

都从哪看到的这个
jackOff
2025 年 5 月 20 日
就这么说吧,写邮件的第三方库都没几个在认真维护,我蹲一个 email.message_from_bytes 的内存爆炸问题都等了好几年了今年才有热心网友愿意自己优化设计,https://github.com/python/cpython/issues/115512
pulutom40
2025 年 5 月 20 日
什么鬼? smtp 协议是基于 tcp 的,websocket 是什么鬼? ws 的话就不是原始的 smtp 协议了,这种出问题要问提供给你 ws 协议的服务方。只看 smtp 命令的话没啥问题,你可以使用 telnet 模拟客户端给 gmail 发信测试
pulutom40
2025 年 5 月 20 日
另外,你都不是基于 tcp 在投件,那你应该是需要发件吧?发件一般是需要先登录的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://study.congcong.us/t/1132845

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX