200分求教SMTP认证的怪问题,各位大侠们请赐教!(分不够再加)

orinyangyang 2005-06-07 08:48:28
小弟写了一个发送邮件的程序,其中SMTP认证模块如下
.... .... ....
'打开对话(在此之前服务器地址,端口都已经正确初始化)
wsock.SendData "EHLO " + wsock.RemoteHost + vbCrLf
wsock.SendData "AUTH LOGIN " + vbCrLf
wsock.SendData Base64EncodeStr(Trim(txtUser.Text)) + vbCrLf
wsock.SendData Base64EncodeStr(Trim(txtPass.Text)) + vbCrLf
.... .... ....
当程序连接一个LOTUS DOMINO服务器时一切正常,该模块的返回信息依次是:
334 VXNlcm5hbWU6
334 UGFzc3dvcmQ6
235 Authentication successful

可问题怪就怪在,当程序连接一个EXCHANGE(2003)服务器时却死活通不过验证(这里保证输入的用户名和密码都是正确的),返回信息如下:
334 VXNlcm5hbWU6
500 5.3.3 Unrecognized command
500 5.3.3 Unrecognized command

多次试验未果,心急如焚,望各位大侠能不吝赐教!谢谢!
...全文
1106 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
tjs1688 2005-08-13
  • 打赏
  • 举报
回复
最近,smtp协议一些大型的邮件服务商增加了一个验证机制,导致以前的[邮件发送/群发]都不好用了。谁知道啊?
orinyangyang 2005-06-10
  • 打赏
  • 举报
回复
多谢各位兄弟的支持,现在问题已经解决。大概原因是:原先是在winsock空件的“dataarrival”的事件中接收数据的,后来怎么都调不通,实在没辙了就自己写了个延时函数(outputdelay)、接收数据函数(GetReturnInfo(iwaittime as integer,strcommand as string) as boolean)手工判断并接收(返回数据),问题就解决了。下面贴出部分源码,请各位大侠指正:

'1.连接SMTP服务器
wsock.Connect
outputdelay 50
If GetReturnInfo(10, "220") = False Then
txtmsg.Text = "邮件服务器连接不上..."
Exit Sub
Else
txtmsg.Text = txtmsg.Text + strReturn + vbCrLf
End If

'2.打开通讯会话
wsock.SendData "EHLO " + wsock.RemoteHost + vbCrLf
outputdelay 50
If GetReturnInfo(10, "250") = False Then
txtmsg.Text = txtmsg.Text + vbCrLf + "无法打开通讯会话..."
Exit Sub
Else
txtmsg.Text = txtmsg.Text + strReturn + vbCrLf
End If

'3.发送登录认证命令
wsock.SendData "AUTH LOGIN " + vbCrLf
outputdelay 50
If GetReturnInfo(10, "334") = False Then
txtmsg.Text = txtmsg.Text + vbCrLf + "没有返回输入用户名提示..."
Exit Sub
Else
txtmsg.Text = txtmsg.Text + strReturn + vbCrLf
End If
'4.输入用户名
wsock.SendData Base64EncodeStr(Trim(txtUser.Text)) + vbCrLf
outputdelay 50
If GetReturnInfo(10, "334") = False Then
txtmsg.Text = txtmsg.Text + vbCrLf + "没有返回输入密码提示..."
Exit Sub
Else
txtmsg.Text = txtmsg.Text + strReturn + vbCrLf
End If
'5.输入密码
wsock.SendData Base64EncodeStr(Trim(txtPass.Text)) + vbCrLf
outputdelay 50
If GetReturnInfo(10, "235") = False Then
txtmsg.Text = txtmsg.Text + vbCrLf + strReturn + vbCrLf + "用户名/密码输入有误,
无法通过验证..."
Exit Sub
Else
txtmsg.Text = txtmsg.Text + strReturn + vbCrLf
End If
'6.'发送发送方地址
wsock.SendData "MAIL FROM:" + Trim(txtFrom.Text) + vbCrLf
outputdelay 50
If GetReturnInfo(10, "250") = False Then
txtmsg.Text = txtmsg.Text + vbCrLf + strReturn + vbCrLf + "发送方地址发送有误..."
Exit Sub
Else
txtmsg.Text = txtmsg.Text + strReturn + vbCrLf
End If

'7.发送接收方地址
Form1 - 2
wsock.SendData "RCPT TO:" + Trim(txtTo.Text) + vbCrLf
outputdelay 50
If GetReturnInfo(10, "250") = False Then
txtmsg.Text = txtmsg.Text + vbCrLf + strReturn + vbCrLf + "接收方地址发送有误..."
Exit Sub
Else
txtmsg.Text = txtmsg.Text + strReturn + vbCrLf
End If

'8.发送消息体
wsock.SendData "DATA" + vbCrLf
outputdelay 50
If GetReturnInfo(10, "354") = False Then
txtmsg.Text = txtmsg.Text + vbCrLf + strReturn + vbCrLf + "发送数据命令有误..."
Exit Sub
Else
txtmsg.Text = txtmsg.Text + strReturn + vbCrLf
End If
'9.发送邮件数据
wsock.SendData mData + vbCrLf
wsock.SendData strContent + vbCrLf
wsock.SendData "." + vbCrLf
If GetReturnInfo(10, "250") = False Then
txtmsg.Text = txtmsg.Text + vbCrLf + strReturn + vbCrLf + "邮件数据发送有误..."
Exit Sub
Else
txtmsg.Text = txtmsg.Text + strReturn + vbCrLf
End If

txtmsg.Text = txtmsg.Text + vbCrLf + "恭喜,邮件发送成功^_^"
wsock.Close
End Sub
lzheng2001 2005-06-09
  • 打赏
  • 举报
回复
楼主可能省略了等待的代码没贴出来吧!
如果这是楼主在程序中的代码的话那的确会有问题,上面已经提到过了,必须等待回应后才能下一条命令
wsock.SendData "EHLO " + wsock.RemoteHost + vbCrLf
wsock.SendData "AUTH LOGIN " + vbCrLf
wsock.SendData Base64EncodeStr(Trim(txtUser.Text)) + vbCrLf
wsock.SendData Base64EncodeStr(Trim(txtPass.Text)) + vbCrLf

应该在每句之间加一个等待的语句
do while ...
doevents
loop
jadeluo 2005-06-09
  • 打赏
  • 举报
回复
SMTP是个会话过程, 象你的代码这样:

wsock.SendData "EHLO " + wsock.RemoteHost + vbCrLf
wsock.SendData "AUTH LOGIN " + vbCrLf
wsock.SendData Base64EncodeStr(Trim(txtUser.Text)) + vbCrLf
wsock.SendData Base64EncodeStr(Trim(txtPass.Text)) + vbCrLf

一下子把所有命令全发送给了SMTP Server, 对于有些SMTP Server来说, 它也许能缓存你所有的命令, 然后逐条执行, 执行后返回执行结果, 再继续逐条执行。而对于有些SMTP Server来说, 可能会丢弃某次接收到的数据中的多余部分, 这时就会出现问题。

正如楼主所说:

而且在DOS模式下这些命令都认识的,
输入 AUTH LOGIN 返回 334 VXNlcm5hbWU6(等待输入用户名)
输入用户名 返回 334 UGFzc3dvcmQ6(等待输入密码)
输入密码 返回 认证结果

这是因为在DOS模式下,你总是每次只发一条命令,等服务器返回执行结果后,再发下一条命令的。这和你现在代码所实现的是不同的。


这条回复说中了要点:

回复人: unsigned(僵哥(当程序语言成为普及滴第三语言之后……)) ( ) 信誉:100 2005-06-08 14:07:00 得分: 0


Auth Login
之后需要等待一条确认指令,然后再传输入用户名一密码。


bwldwb6 2005-06-09
  • 打赏
  • 举报
回复
关心,帮你顶下
希望有高手解决
orinyangyang 2005-06-09
  • 打赏
  • 举报
回复
不好意思,是我发贴时忽略了(多写了一行),对方的EXCHANGE服务器实际上确实是支持AUTH LOGIN的

wsock.SendData "AUTH LOGIN " + vbCrLf
wsock.SendData Base64EncodeStr(Trim(txtUser.Text)) + vbCrLf
wsock.SendData Base64EncodeStr(Trim(txtPass.Text)) + vbCrLf
.... .... ....
当程序连接一个LOTUS DOMINO服务器时一切正常,该模块的返回信息依次是:
334 VXNlcm5hbWU6
334 UGFzc3dvcmQ6
235 Authentication successful

可问题怪就怪在,当程序连接一个EXCHANGE(2003)服务器时却死活通不过验证(这里保证输入的用户名和密码都是正确的),返回信息如下:
334 VXNlcm5hbWU6
500 5.3.3 Unrecognized command
500 5.3.3 Unrecognized command
lzheng2001 2005-06-08
  • 打赏
  • 举报
回复
你发的每个命令都应该等待对方服务器的回应才继续发送下一下命令,不知你的程序是否有这样做?
orinyangyang 2005-06-08
  • 打赏
  • 举报
回复
EXCHANGE服务器是支持AUTH LOGIN的,HELP命令返回信息里包含AUTH。
而且在DOS模式下这些命令都认识的,
输入 AUTH LOGIN 返回 334 VXNlcm5hbWU6(等待输入用户名)
输入用户名 返回 334 UGFzc3dvcmQ6(等待输入密码)
输入密码 返回 认证结果

这到底是怎么回事啊,555... ...
lzheng2001 2005-06-08
  • 打赏
  • 举报
回复
看了一下你的信息发现对方不认AUTH LOGIN 这个命令!
wsock.SendData "AUTH LOGIN " + vbCrLf

建议在DOS模式下用telnet命令连接到服务器,然后执行help 命令查看一下对方支持什么命令
有可能是 "AUTO" 或 "LONIN" 任意一个单词就可以了
lzheng2001 2005-06-08
  • 打赏
  • 举报
回复
试试这样吧,发个空的用户密码,看他有什么反应.
wsock.SendData "AUTH LOGIN " + vbCrLf
wsock.SendData vbCrLf
wsock.SendData vbCrLf
orinyangyang 2005-06-08
  • 打赏
  • 举报
回复
得到334 VXNlcm5hbWU6的信息明明是提示输入用户名的,但系统为什么把下面的输入内容当成是SMTP命令来解析呢(从返回信息500 5.3.3 Unrecognized command可以看出他是把输入内容当成是命令来识别了呀)?焦急等待种,各位高手继续支招啊!!!!!
wumylove1234 2005-06-08
  • 打赏
  • 举报
回复
对啊.这得看对方的服务器是否要求验证啊.
orinyangyang 2005-06-08
  • 打赏
  • 举报
回复
EXCHANGE服务器开通了验证功能,如果不验证直接执行“Mail From:”会提示:
454 5.7.3 Client was not authenticated.


实在是着急,各位大侠发表高见啊,分绝对不是问题!
lzheng2001 2005-06-08
  • 打赏
  • 举报
回复
根据你贴出来的信息,对方应该是首先不认AUTH LOGIN 这个命令吧,你对比一下是不是这样?
wsock.SendData "EHLO " + wsock.RemoteHost + vbCrLf => 334 VXNlcm5hbWU6
wsock.SendData "AUTH LOGIN " + vbCrLf => 500 5.3.3 Unrecognized command
wsock.SendData Base64EncodeStr(Trim(txtUser.Text)) + vbCrLf => 500 5.3.3 Unrecognized command
wsock.SendData Base64EncodeStr(Trim(txtPass.Text)) + vbCrLf


orinyangyang 2005-06-08
  • 打赏
  • 举报
回复
加了doevents试了还是不行啊,5。。。。
crycoming 2005-06-08
  • 打赏
  • 举报
回复
unsigned的意思是?
wsock.SendData "EHLO " + wsock.RemoteHost + vbCrLf
doevents
wsock.SendData "AUTH LOGIN " + vbCrLf
doevents
wsock.SendData Base64EncodeStr(Trim(txtUser.Text)) + vbCrLf
doevents
wsock.SendData Base64EncodeStr(Trim(txtPass.Text)) + vbCrLf
doevents
orinyangyang 2005-06-08
  • 打赏
  • 举报
回复
unsigned(僵哥(当程序语言成为普及滴第三语言之后……)) 兄:
能说的具体点吗?我具体怎么拦截OE的发送命令(格式)啊?

还有啊,我现在却是是在“AUTH LOGIN”命令返回之后才发的用户名和密码啊,为什么还是通不过验证呢? 我有一点不明白的是:他(EXCHANGE)为什么会把我在AUTH LOGIN 后输入的用户名和密码当成是SMTP命令来解析呢?请多指教,谢谢!!!
僵哥 2005-06-08
  • 打赏
  • 举报
回复
Auth Login
之后需要等待一条确认指令,然后再传输入用户名一密码。
僵哥 2005-06-08
  • 打赏
  • 举报
回复
对于Exchange确实有点问题,即使认证通过了,然后到传输邮件内容时会出现莫明其妙的错误,偶试着拦截掉OE(Outlook Express)的发送内容,是可以滴,不知道是否客户端信息也模仿OE就可以,没做进一步测试。
其实在很多时候确实可以使用OE来测试的,也就是用程序在本机监听端口,然后把OE的服务器地址设为本机的,然后让OE连自己的程序,同时程序记录相关传入的命令,然后程序再连接远程服务器,做个转发,然后再把传回的内容做记录,最后转发给OE。
orinyangyang 2005-06-08
  • 打赏
  • 举报
回复
我已经在winsock空件的DataArrival时间里写了取返回数据的代码了呀。现在的问题是:同样的程序在连接DOMINO服务器是正常的,但连接EXCHANGE服务器时就死活不能验证啊!!!!!
加载更多回复(1)

7,765

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧