2017-09-12 10 views
0

많은 연구를 한 후 Google의 Gmail 서버를 사용하여 SMTP 이메일을 보낼 수있었습니다. Windows 및 Linux에서 CPython과 동일한 코드를 사용하고 있지만 ESP8266 또는 Unix 포트에서 Micropython 1.9.2 (최신 9 월 11 일)에서 코드를 사용하려고 시도하면 63 행에 코드가 잠기지 만 이유를 알 수 없습니다.SMTP가있는 ESP8226 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) 

코드 (예, 한 번 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() 
허용 대답 함께

업데이트 된 코드 (예 , 나는 추한 것을 알고있다) 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)

(자세히 좀 단순화와 함께, 파이썬 스트림 의미를 일치하는) MicroPython 스트림 의미에 대해 읽어 보시기 바랍니다 : http://docs.micropython.org/en/latest/pyboard/library/uio.html?#conceptual-hierarchy

인용 된 상태 (MicroPython은 기본적으로 "버퍼링 된 스트림"Python 의미 체계를 따릅니다.) 그렇게 많은 양의 데이터가 없다면, .read()은 충분히 도착할 때까지 (또는 EOF 나 오류가 발생할 때까지) 참을성있게 기다릴 것입니다.

SMTP 프로토콜은 줄 단위이므로 .readline()을 사용해야합니다.

+0

통찰력을 가져 주셔서 감사 드리며 조금 조정 해 주셨지만 권장 사항이 적용되었습니다. 첨부 된 문서를 검토합니다 (두 번 고맙습니다). – jawbreaker79