2017-09-12 8 views
0

多くの調査をした後、私はGoogleのGmailサーバーを使ってSMTPメールを送信することができました。私はWindowsとLinuxの両方でCPythonで問題なく同じコードを使用していますが、ESP8266またはUnixポートでMicropython 1.9.2(最新の9月11日)のコードを使用しようとすると、コードは63行目にロックされますが、理由を理解できません。ESP8226 SMTPによるmicropython ssl接続の問題

私が考えることができる唯一の他のことは、MicropythonのSSL実装が十分ではなく、CPython SSLを移植する必要があるということです。

ありがとうございます。

問題のコードは次のとおりです。

61 heloCommand = 'EHLO Alice\r\n' 
62 ssl_clientSocket.write(heloCommand.encode()) 
63 recv1 = ssl_clientSocket.read(1024) 
64 print(recv1) 

CODE(はい、私は一度micropythonで働いて、それは醜いです知っているし、それをクリーンアップする予定):

# Micropython 
try: 
    import usocket as socket 
    #import base64 
    import ussl as ssl 

except: 
# Python version 3 
    import socket 
    #import base64 
    import ssl 


msg = """From: [email protected] 
To: [email protected] 
Subject: Testing 

Testing transmission thru python 
""" 
endmsg = "\r\n.\r\n" 

recipient = "[email protected]" 
sender = "[email protected]" 
username = "[email protected]" 
password = 'Mary_Had_A_Password_of_123' 

# Choose a mail server (e.g. Google mail server) and call it mailserver 
mailserver = "smtp.gmail.com" 
port = 587 

# Create socket called clientSocket and establish a TCP connection with mailserver 
clientSocket = socket.socket() 
clientSocket.connect(socket.getaddrinfo(mailserver, port)[0][-1]) 
recv = clientSocket.recv(1024) 
print(recv) 
print(recv[:3]) 
if recv[:3] != b'220': 
    print('220 reply not received from server.') 

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

# Request an encrypted connection 
startTlsCommand = 'STARTTLS\r\n' 
clientSocket.send(startTlsCommand.encode()) 
tls_recv = clientSocket.recv(1024) 
print(tls_recv) 
if tls_recv[:3] != b'220': 
    print('220 reply not received from server') 

# Encrypt the socket 
#ssl_clientSocket = ssl.wrap_socket(clientSocket, ssl_version=ssl.PROTOCOL_TLSv1) 
ssl_clientSocket = ssl.wrap_socket(clientSocket) 
print("Secure socket created") 

heloCommand = 'EHLO Alice\r\n' 
ssl_clientSocket.write(heloCommand.encode()) 
recv1 = ssl_clientSocket.read(1024) 
print(recv1) 

# Send the AUTH LOGIN command and print server response. 
authCommand = 'AUTH LOGIN\r\n' 
ssl_clientSocket.write(authCommand.encode()) 
auth_recv = ssl_clientSocket.read(1024) 
print(auth_recv) 
if auth_recv[:3] != b'334': 
    print('334 reply not received from server') 

print("Sending username/password") 
# Send username and print server response. 
#uname = base64.b64encode((username).encode()) 
uname=b'Base64EncryptedUser==' 
pword=b'Base64EncryptedPassword' 
print(str(uname)) 
ssl_clientSocket.write(uname) 
ssl_clientSocket.write('\r\n'.encode()) 
uname_recv = ssl_clientSocket.read(1024) 
print(uname_recv) 
if uname_recv[:3] != b'334': 
    print('334 reply not received from server') 

# Send password and print server response. 
#pword = base64.b64encode((password).encode()) 
print(str(pword)) 
ssl_clientSocket.write(pword) 
ssl_clientSocket.write('\r\n'.encode()) 
pword_recv = ssl_clientSocket.read(1024) 

print(pword_recv) 
if pword_recv[:3] != b'235': 
    print('235 reply not received from server') 

# Send MAIL FROM command and print server response. 
mailFromCommand = 'MAIL FROM: <' + sender + '>\r\n' 
ssl_clientSocket.write(mailFromCommand.encode()) 
recv2 = ssl_clientSocket.read(1024) 
print(recv2) 
if recv2[:3] != b'250': 
    print('250 reply not received from server.') 

# Send RCPT TO command and print server response. 
rcptToCommand = 'RCPT TO: <' + recipient + '>\r\n' 
ssl_clientSocket.write(rcptToCommand.encode()) 
recv3 = ssl_clientSocket.read(1024) 
print(recv3) 
if recv3[:3] != b'250': 
    print('250 reply not received from server.') 

# Send DATA command and print server response. 
dataCommand = 'DATA\r\n' 
ssl_clientSocket.write(dataCommand.encode()) 
recv4 = ssl_clientSocket.read(1024) 
print(recv4) 
if recv4[:3] != b'354': 
    print('354 reply not received from server.') 

# Send message data. 
ssl_clientSocket.write(msg.encode()) 

# Message ends with a single period. 
ssl_clientSocket.write(endmsg.encode()) 
recv5 = ssl_clientSocket.read(1024) 
print(recv5) 
if recv5[:3] != b'250': 
    print('250 reply not received from server.') 

# Send QUIT command and get server response. 
quitCommand = 'QUIT\r\n' 
ssl_clientSocket.write(quitCommand.encode()) 
recv6 = ssl_clientSocket.read(1024) 
print(recv6) 
if recv6[:3] != b'221': 
    print('221 reply not received from server.') 

clientSocket.close() 
受け入れ答えWITH

更新されたコード(はい、私はそれが醜いことが分かっている)read(1024)がssl socketのreadline()に置き換えられています。また、ssl EHLOコマンドの後にバッファをクリーニングする方法を追加する必要があります。最初のEHLOでrecvCount = recv1.decode()。count( '\ n')を追加し、同じカウントでssl EHLOのループを追加します。

# Micropython 
try: 
    import usocket as socket 
    #import base64 
    import ussl as ssl 

except: 
# Python version 3 
    import socket 
    #import base64 
    import ssl 


msg = """From: [email protected] 
To: [email protected] 
Subject: Testing 

Testing transmission thru python 
""" 
endmsg = "\r\n.\r\n" 

recipient = "[email protected]" 
sender = "[email protected]" 
username = "[email protected]" 
password = 'Mary_Had_A_Password_of_123' 

# Choose a mail server (e.g. Google mail server) and call it mailserver 
mailserver = "smtp.gmail.com" 
port = 587 

# Create socket called clientSocket and establish a TCP connection with mailserver 
clientSocket = socket.socket() 
clientSocket.connect(socket.getaddrinfo(mailserver, port)[0][-1]) 
recv = clientSocket.recv(1024) 
print(recv) 
print(recv[:3]) 
if recv[:3] != b'220': 
    print('220 reply not received from server.') 

# Send HELO command and print server response. 
heloCommand = 'EHLO Alice\r\n' 
clientSocket.send(heloCommand.encode()) 
recv1 = clientSocket.recv(1024) 
recvCount=recv1.decode().count('\n') 
print(recv1) 
if recv1[:3] != b'250': 
    print('250 reply not received from server.') 

# Request an encrypted connection 
startTlsCommand = 'STARTTLS\r\n' 
clientSocket.send(startTlsCommand.encode()) 
tls_recv = clientSocket.recv(1024) 
print(tls_recv) 
if tls_recv[:3] != b'220': 
    print('220 reply not received from server') 

# Encrypt the socket 
#ssl_clientSocket = ssl.wrap_socket(clientSocket, ssl_version=ssl.PROTOCOL_TLSv1) 
ssl_clientSocket = ssl.wrap_socket(clientSocket) 
print("Secure socket created") 

heloCommand = 'EHLO Alice\r\n' 
ssl_clientSocket.write(heloCommand.encode()) 
recv1='' 
for index in range(0,recvCount): 
    recv1 = recv1+ssl_clientSocket.readline().decode() 
print(recv1) 

# Send the AUTH LOGIN command and print server response. 
authCommand = 'AUTH LOGIN\r\n' 
ssl_clientSocket.write(authCommand.encode()) 
auth_recv = ssl_clientSocket.readline() 
print(auth_recv) 
if auth_recv[:3] != b'334': 
    print('334 reply not received from server') 

print("Sending username/password") 
# Send username and print server response. 
#uname = base64.b64encode((username).encode()) 
uname=b'Base64EncryptedUser==' 
pword=b'Base64EncryptedPassword' 
print(str(uname)) 
ssl_clientSocket.write(uname) 
ssl_clientSocket.write('\r\n'.encode()) 
uname_recv = ssl_clientSocket.readline() 
print(uname_recv) 
if uname_recv[:3] != b'334': 
    print('334 reply not received from server') 

# Send password and print server response. 
#pword = base64.b64encode((password).encode()) 
print(str(pword)) 
ssl_clientSocket.write(pword) 
ssl_clientSocket.write('\r\n'.encode()) 
pword_recv = ssl_clientSocket.readline() 

print(pword_recv) 
if pword_recv[:3] != b'235': 
    print('235 reply not received from server') 

# Send MAIL FROM command and print server response. 
mailFromCommand = 'MAIL FROM: <' + sender + '>\r\n' 
ssl_clientSocket.write(mailFromCommand.encode()) 
recv2 = ssl_clientSocket.readline() 
print(recv2) 
if recv2[:3] != b'250': 
    print('250 reply not received from server.') 

# Send RCPT TO command and print server response. 
rcptToCommand = 'RCPT TO: <' + recipient + '>\r\n' 
ssl_clientSocket.write(rcptToCommand.encode()) 
recv3 = ssl_clientSocket.readline() 
print(recv3) 
if recv3[:3] != b'250': 
    print('250 reply not received from server.') 

# Send DATA command and print server response. 
dataCommand = 'DATA\r\n' 
ssl_clientSocket.write(dataCommand.encode()) 
recv4 = ssl_clientSocket.readline() 
print(recv4) 
if recv4[:3] != b'354': 
    print('354 reply not received from server.') 

# Send message data. 
ssl_clientSocket.write(msg.encode()) 

# Message ends with a single period. 
ssl_clientSocket.write(endmsg.encode()) 
recv5 = ssl_clientSocket.readline() 
print(recv5) 
if recv5[:3] != b'250': 
    print('250 reply not received from server.') 

# Send QUIT command and get server response. 
quitCommand = 'QUIT\r\n' 
ssl_clientSocket.write(quitCommand.encode()) 
recv6 = ssl_clientSocket.readline() 
print(recv6) 
if recv6[:3] != b'221': 
    print('221 reply not received from server.') 

clientSocket.close() 

答えて

0

recv1 = ssl_clientSocket.read(1024)

(密接にちょうどいくつかの単純化して、Pythonのストリームセマンティクスと一致する)MicroPythonストリームのセマンティクスについてについてお読みください: http://docs.micropython.org/en/latest/pyboard/library/uio.html?#conceptual-hierarchy

引用された状態正確に1024のデータを要求しています(MicroPythonは、デフォルトで「バッファードストリーム」のPythonセマンティクスに従います)。それほど多くのデータがない場合、.read()は十分に到着するまで(またはEOFまたはエラーが発生するまで)辛抱強く待ちます。

SMTPプロトコルは回線指向なので、代わりに.readline()を使用する必要があります。

+0

あなたの洞察をいただきありがとうございます、少し微調整しましたが、あなたの推薦が働きました。添付のドキュメントを再検討します(ダブルありがとうございます)。 – jawbreaker79