2017-02-18 91 views
0

我正在編寫一個Python腳本來設置套接字以通過SMTP從我的Gmail帳戶發送帶有圖像的多部分電子郵件。我沒有將smtplib或email.mime用於教育目的。我使用ssl和套接字並用ssl.wrap_socket封裝一個TCP套接字。SMTP到Gmail:圖像被添加的CRLFs損壞

一切正常,電子郵件到達與文字和附加圖像。但是,附加的JPEG圖像已損壞。

在十六進制編輯器中比較原始圖像和損壞的圖像,我可以看到jpeg中的所有0x0D和0x0A字節都被0x0D0x0A取代。這些字節代表文本中的CR和LF,所以看起來在某些時刻,CR和LF在我的二進制數據中被CRLF不適當地替換。

如果我在將它發送到ssl套接字之前立即將它寫入文件,二進制數據看起來是正確的。 Gmail似乎正確解釋了內容類型,因爲它將損壞的圖像顯示爲圖像。

CRLF替換可能會蔓延到二進制圖像數據的任何想法?

解決方案:

的編碼頭相關的解決方案代碼:

 b'Content-Transfer-Encoding: base64\r\n' +\ 

而對於base64編碼本身:

clientSocketSSL.sendall(base64.b64encode(msgImage)) 
+0

也許你應該使用更高級別的模塊,如果你不想了解協議的所有細節,並讓它做「正確的事情」。如果您確實想要使用套接字,請深入MIME RFC。 – Cans

回答

1

既然你不顯示任何代碼,我的猜測是你簡單地把二進制圖像放入郵件。但是,傳統上,郵件只能傳輸ASCII數據,並且線路長度限制爲1000個字符,因此必須對數據進行傳輸編碼,有關更多信息,請參見Wikipedia:MIME

如果你沒有指定任何傳輸編碼,它將被視爲7bit,如果你是幸運的8bit編碼,並且這兩種編碼都將行結束視爲特殊行爲,並將根據平臺進行更改。這意味着在Windows上原始的單個LF將被存儲爲CRLF,並且在Unix上原始的CRLF將僅被存儲爲LF。請注意,不僅發送和接收郵件用戶代理可能會將數據調整到平臺,但其間的任何郵件服務器也可能會更改這些數據。

總結:使用MIME正確編碼傳輸的二進制數據,email提供您需要的功能。

+0

感謝編碼的提示。看到我上面的編輯爲我迄今做了什麼,但我會繼續調查這一點。 – TonyM

+0

@TonyM:就像我期望的那樣,即沒有像base64這樣的適當的傳輸安全編碼。除此之外,您應該將電子郵件視爲字節而不是UTF-8編碼數據。 –

+0

是的,base64編碼解決了它! – TonyM