热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

我的邮箱客户端程序Popmail

05年的时候写了一个邮箱客户端程序。当时主要目的是研究POP3和SMTP协议,同时锻炼自己的网络编程能力。当然了,如果自己写的邮箱客户端能够满足自身的日常工作需要,而不是频繁的登录

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写的程序就是这样的,古朴大方。。。。。



推荐阅读
  • 本文整理了一份基础的嵌入式Linux工程师笔试题,涵盖填空题、编程题和简答题,旨在帮助考生更好地准备考试。 ... [详细]
  • 在使用 Nginx 作为服务器时,发现 Chrome 能正确从缓存中读取 CSS 和 JS 文件,而 Firefox 却无法有效利用缓存,导致加载速度显著变慢。 ... [详细]
  • 深入探讨前端代码优化策略
    本文深入讨论了前端开发中代码优化的关键技术,包括JavaScript、HTML和CSS的优化方法,旨在提升网页加载速度和用户体验。 ... [详细]
  • 本文详细介绍了如何在ARM架构的目标设备上部署SSH服务端,包括必要的软件包下载、交叉编译过程以及最终的服务配置与测试。适合嵌入式开发人员和系统集成工程师参考。 ... [详细]
  • Flutter 核心技术与混合开发模式深入解析
    本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
  • 在Ubuntu 18.04上使用Nginx搭建RTMP流媒体服务器
    本文详细介绍了如何在Ubuntu 18.04上使用Nginx和nginx-rtmp-module模块搭建RTMP流媒体服务器,包括环境搭建、配置文件修改和推流拉流操作。适用于需要搭建流媒体服务器的技术人员。 ... [详细]
  • 在Java开发中,保护代码安全是一个重要的课题。由于Java字节码容易被反编译,因此使用代码混淆工具如ProGuard变得尤为重要。本文将详细介绍如何使用ProGuard进行代码混淆,以及其基本原理和常见问题。 ... [详细]
  • RTThread线程间通信
    线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ... [详细]
  • 本文将详细介绍如何使用PHP获取文件夹的大小,包括子文件夹的大小,并提供实用的代码示例。 ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中安装 Python 3.7 的步骤,包括编译工具的安装、Python 3.7 源码的下载与编译、软链接的创建以及常见错误的处理方法。 ... [详细]
  • 本文详细记录了 MIT 6.824 课程中 MapReduce 实验的开发过程,包括环境搭建、实验步骤和具体实现方法。 ... [详细]
  • mybatis 详解(七)一对一、一对多、多对多
    mybatis详解(七)------一 ... [详细]
  • Cookie学习小结
    Cookie学习小结 ... [详细]
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • 在腾讯云服务器上部署Nginx的详细指南中,首先需要确保安装必要的依赖包。如果这些依赖包已安装,可直接跳过此步骤。具体命令包括 `yum -y install gcc gcc-c++ wget net-tools pcre-devel zlib-devel`。接下来,本文将详细介绍如何下载、编译和配置Nginx,以确保其在腾讯云服务器上顺利运行。此外,还将提供一些优化建议,帮助用户提升Nginx的性能和安全性。 ... [详细]
author-avatar
mobiledu2502897207
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有