05年的時候寫了一個郵箱客戶端程式,當時主要目的是研究POP3和SMTP協議,同時鍛煉自己的網路編程能力,當然了,如果自己寫的郵箱客戶端能夠滿足自身的日常作業需要,而不是頻繁的登錄不同的網頁郵箱,那就再好不過了,時隔16年,給popmail增加了SSL(TLS 1.2)會話,感覺安全了一點,郵件再也不用裸奔了,看到16年前的代碼,非常感慨,隨便寫寫,特此紀念,
POP3和SMTP這兩個協議本身都很簡單,但實作起來還是有很大難度,尤其是你希望把它寫的健壯、易用或者產品化的時候,
比如HTTP協議也很簡單,寫個簡單的socket程式通過GET命令就能把網頁給down下來,但接收大的網路資源就復雜多了,何時決議、如何決議完整的HTTP回應頭,就是個頭疼問題,因為你不能指望一次recv就能接收完所有回應資料,也不能指望服務器先發送HTTP回應頭,然后再發送回應資料,只有把HTTP回應頭徹底決議了,我們才能知道后續接收的Body資料有多大,何時才能接收完畢,
比如通過回應頭的"Content-Length"欄位,才能知道后續Body的大小,這個大小可能超過了你之前開辟的接收資料快取區大小,當然你可以在得知Body大小后,重新開辟一個與"Content-Length"一樣大小的快取區,但這樣做顯然是不明智的,比如你get的是一部4K高清藍光小電影,藍光電影不一定能get到,藍屏電腦倒有可能get到,,,,,,
遇到服務器明確給出"Content-Length"欄位,是一件值得額手稱慶的大喜事,但不是每個IT民工都這么幸運,如果遇到的是不靠譜的服務器,發送的是"Transfer-Encoding: chunked",那你就必須鍛煉自己真正的決議和組織能力了,這些分塊傳輸的資料,顯然不會以你接收的節奏到達你的緩沖區,比如先接收到一個block塊大小,然后是一個完整的塊資料,很有可能你會接收到多個塊或者不完整的塊,這就需要你站在宏觀的角度把他們拼接起來,
如果你遇到的是甩的一米的服務器,它不僅給你的是chunked,而且還增加了"Content-Encoding: gzip",那么你就需要拼接后進行解壓,當然你也可能遇到的是"deflate"壓縮,
題外話:我一直困惑的是HTTP協議為何不是對分塊資料單獨gzip壓縮然后傳輸,而只能是整體gzip壓縮后再分塊傳輸,這個對大資源傳輸很關鍵,比如上面的4K高清藍光小電影,顯然不能通過gzip+chunked方式傳輸,土豪服務器例外,
當然你也可以用開源的llhttp來決議收到的http資料,從而避免上述可能會遇到的各種坑,最新版本的nodejs中就使用llhttp代替之前的的http-parser,據說決議效率有大幅提升,為此我下載了nodejs原始碼,并編譯了一把,這是一個快樂的程序,因為你可以看到v8引擎,openssl,zlib等各種開源庫,,,,,不過llhttp只負責決議,不負責快取,因此你還是需要在決議的程序中,進行資料快取,這是我寫的通過llhttp決議http回應資料的案例:
基于SSL(TLS)的HTTPS網頁下載——如何撰寫健壯的可靠的網頁下載
這里面有我封裝好的sslite.dll庫可以方便的幫助你進行SSL客戶端通信,目前支持TLS1.2,我的popmail因為使用sslite庫才把衣服穿上避免了裸奔,
花開兩朵各表一枝,還是回到POP3/SMTP上來,
相較而言,實作POP3要比實作SMTP復雜,這個復雜不是指協議本身有多復雜,也不是POP3比SMTP多了幾個命令,而是指用代碼實作協議的難度,尤其是決議難度,POP3是接收協議,SMTP是發送協議,總體而言發送比接收要簡單很多,
因為發送資料的時候你可以耍流氓,不管服務器的死活,可以變態的1個位元組1個位元組發資料,也可以忽長忽短的發資料,從而讓服務器猜不透你,直到把資料全部發送完畢,但接收資料就復雜多了,比如上面提到的如何接收HTTP回應資料,現在需要你來面對猜不透的服務器了,因為服務器也可能耍流氓,
早期的email協議只支持ASCII碼這種純文本傳輸,后來隨著富文本的出現,影像、檔案也迫切需要通過email進行傳輸,這時MIME協議誕生了,MIME的出現更多的是一種向下兼容的無奈,而不是革命,通過對二進制資料或非ASCII碼資料進行base64或quoted-printable編碼,來實作純ASCII碼的傳輸,顯然這種方式會讓你的郵件體變大,傳輸效率下降,
傳輸下降只是一方面,決議MIME格式的郵件也是一件頭疼的事,對于"Content-Type: multipart/mixed"來說,需要根據boundary值,將不同mixed part郵件體給決議出來,同時你要面臨各種編碼格式,否則你的郵件標題、附件名稱就會出現亂碼,比如這種:"=?gb2312?B?=",比如這種:"=?gb2312?Q?",又比如這種"=?unicode-1-1-utf-7?q?",,,,,當時還還遇到過"Content-type: message/rfc822",或者"content-disposition : inline"欄位,完全處于懵B狀態,05年的時候,網上資料特別少,也不認識張小龍,張小龍不僅是微信之父,更是Foxmail之母,如果當時能聯系上,可能會發微信咨詢一下,或者qq加好友哦,,,,,,,但在當年只能連蒙帶猜,遇到一次亂碼就猜測著決議看看,敢于在踩雷中決議,在決議中踩雷,
當年寫郵箱客戶端使用的是經典的VC6.0,也許很多90后、00后、10后沒有聽說過它,沒關系,沒關系,下面就是用VC6撰寫的popmail,不高調,不奢華,一眼就能看出vc6的影子,它支持多郵箱賬戶、郵件自動接收、快速查看郵件串列、遠程洗掉郵件,自動回復等人民群眾喜聞樂見卻基本不用的功能,
Popmail客戶端下載地址
1、主界面

2、多郵箱賬戶配置

3、賬戶配置

4、自動規則設定

5、接收郵件

6、快速查看

為什么不能把界面寫的多姿多彩呢?VC6寫的程式就是這樣的,古樸大方,,,,,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/390263.html
標籤:其他
上一篇:如何高效撰寫測驗用例?
下一篇:聊齋-河間生
