2013-11-02 125 views
2

我必须在Python中为类编写一个SMTP邮件客户端,并且卡在作业的第一部分。经过很多麻烦我已经得到了这么多(目前使用免费的便携式SMTP服务器,但以后需要使用SSL或TLS的Gmail)。以下是我的代码。当它到达代码的RCPT TO部分时,我得到一个500语法错误。谁能帮忙?SMTP邮件客户端Python

from socket import * 
msg = "\r\n I love computer networks!" 
endmsg = "\r\n.\r\n" 

# Choose a mail server 
mailServer = 'localhost' 
mailPort = 25 

# Create socket called clientSocket and establish a TCP connection with mailserver 
clientSocket = socket(AF_INET,SOCK_STREAM) 
clientSocket.connect((mailServer, mailPort)) 
recv = clientSocket.recv(1024) 
print 'test' 
print recv 
if recv[:3] != '220': 
    print '220 reply not received from server.' 

# Send HELLO command and print server response. 
helloCommand = 'HELO Alice\r\n'; 
clientSocket.send(helloCommand) 
recv1 = clientSocket.recv(1024) 
print recv1 
if recv1[:3] != '250': 
    print '250 reply not received from server.' 

# Send MAIL FROM command and print server response. 
#command = "STARTTLS\r\n" 
#clientSocket.send(command) 
#recva = clientSocket.recv(1024) 
#print(recva) 
mailfromCommand = 'MAIL FROM: <[email protected]>\r\n.' 
clientSocket.send(mailfromCommand) 
recv1 = clientSocket.recv(1024) 
print(recv1) 
if recv1[:3] != '250': 
    print('mail from 250 reply not received from server.') 

# Send RCPT TO command and print server response. 
rcpttoCommand = 'RCPT TO: <[email protected]>\r\n' 
clientSocket.send(rcpttoCommand) 
recv1 = clientSocket.recv(1024) 
print(recv1) 
if recv1[:3] != '250': 
    print('rcpt to 250 reply not received from server.') 

# Send DATA command and print server response 
dataCommand = 'Data' 
print(dataCommand) 
clientSocket.send(dataCommand) 
recv1 = clientSocket.recv(1024) 
print(recv1) 
if recv1[:3] != '250': 
    print('data 250 reply not received from server.') 

# Send message data. 
message = raw_input('Enter Message Here: ') 

# Fill in end# Message ends with a single period. 
mailMessageEnd = '\r\n.\r\n' 
clientSocket.send(message + mailMessageEnd) 
recv1 = clientSocket.recv(1024) 
print(recv1) 
if recv1[:3] != '250': 
    print('end msg 250 reply not received from server.') 

# Send QUIT command and get server response. 
quitCommand = 'Quit\r\n' 
print(quitCommand) 
clientSocket.send(quitCommand) 
recv1 = clientSocket.recv(1024) 
print(recv1) 
if recv1[:3] != '250': 
    print('quit 250 reply not received from server.') 

    pass 

if __name__ == '__main__': 
    main() 

结果:

test 
220 localhost 


250 Hello localhost 


250 [email protected] Address Okay 


RCPT TO: <[email protected]> 


500 Syntax Error 


rcpt to 250 reply not received from server. 
Data 
+0

您是否被禁止使用标准库和/或第三方软件包中的['smtplib'](http://docs.python.org/2/library/smtplib.html)? – abarnert

+0

同时,[TCP套接字是字节流,而不是消息流](http://stupidpythonideas.blogspot.com/2013/05/sockets-are-byte-streams-not-message.html)。每个'recv'可以从服务器获得半行数据,或者七个半行;你不能假设每个人都得到一条线。你需要缓冲和解析。或者只是使用'makefile'让Python做到这一点(它适用于像SMTP这样的任何一行一行的协议),并且使用'sendall'而不是'send',就完成了。 – abarnert

+0

我们得到了一个基本的骨架代码,直到MAIL FROM命令完成。之后,我们必须填写其余的。 – user2946832

回答

1

最可能出现的问题,这是一个:

mailfromCommand = 'MAIL FROM: <[email protected]>\r\n.' 

注意额外的.在结束了吗?所以,您发送的服务器最终被:

MAIL FROM: <[email protected]> 
.RCPT TO: <[email protected]> 

而且.RCPT是一个语法错误。


但是,在代码中还有两个非常严重的问题。

第一个是不能保证send发送给你的所有数据。这就是为什么它返回实际发送的字节数。所以,你可能很容易把它发送给一个命令的一部分。

这一个是微不足道的解决:只使用sendall而不是send


第二个问题是,不能保证每个recv只会得到一行数据。一个recv可能会得到6个字符,然后是下一个19行。 TCP sockets are byte streams, not message streams,您可以根据协议在其上为其构建消息流。

想象一下,如果在recv之后得到250 [email protected] Addr,接下来ess OK\r\n250 [email protected] Address OK\r\n会发生什么情况。你要检查第二个是否以250开头,发现它没有,并失败。

这个问题在一般情况下并不像解决问题那么简单 - 通常您必须缓冲和解析消息,这意味着要么编写一个生成器,要么完全重新组织代码。

但是在像SMTP这样的逐行协议的情况下,很容易:只需使用makefile,它可以让您返回一个文件对象,您可以迭代或调用readline,它会奇迹般地处理缓冲您。


看起来所有这三个错误显然都在你老师给你的代码中。更别说在helloCommand = 'HELO Alice\r\n'(这是一个由实际上并不知道Python的人编写的代码的红色标志)结尾的流浪分号。你可能想要阅读Socket Programming HOWTO,或者更好的是,一个更完整的教程(Google可以为你找到),这样你就可以学习如何真正编写工作程序,而不是破坏性的废话,几乎99%的时间在本地主机上运行当电脑的平台不太忙时。

+0

谢谢你的收获。我非常感谢你的帮助,但它看起来像这个骨架代码也来自我们的教科书。我之前从未使用Python进行过编程,所以我只是试图让它起作用。我已经通过了这个错误,但现在当我回到“在这里输入信息:”的部分时,我在shell中得到提示并输入消息并回车,但是程序什么都不做。我做了一些谷歌搜索,看到了这个人的视频,我看不出他和我的代码之间有很多差异。 http://strantalis.wordpress.com/2012/10/14/python-assignment-3-smtp-client/ – user2946832

+0

@ user2946832:堆栈溢出不是一个很好的方式让别人来互动地调试你的程序,修复你的每个问题一个接一个地跑。你问为什么你得到那500错误,我解释了它,现在你的代码的那部分工作。如果你有一个新问题,并且你认为值得问这个问题,接受这个答案,然后问一个新问题(把每个问题链接到另一个问题)。 – abarnert

+0

@ user2946832:与此同时,额外的“。”在教科书里?然后进入教科书的网站,看看他们是否有“勘误”部分。如果他们这样做,它应该告诉你他们发布的代码中的所有错误,以及如何修复它们。 – abarnert