趣文:Email 诞生记

前言:本文主要介绍 Email 的原理和协议, 人物,公司,情节纯属虚构,请勿对号入座。


上个世纪80年代初, 小王从计算机系毕业了, 进入了很多人梦寐以求的MSHP公司,一入职老板就给小王安排了一个导师:资深的程序员老周 。

为每个新人都安排一个导师, 也是公司一直以来的好传统。

老板要求老周带着小王尽快进入工作状态, 为公司设计一个简单的电子邮件系统。

一、初次见面

周一的早上, 小王见到了师傅老周。

老周拍了拍小王的肩膀 : “小王, 听说你大学计算机学的不错, 老板交代的可是你工作以来第一项任务, 一定要好好干啊”

“可是我实在不知道电子邮件系统是啥啊?! ”, 小王面露难色。

“主要是你不了解背景” 老周说,“其实是这样的, 我们公司有很多IBM刚出的兼容机, 甚至都有服务器了, 所以老板想设计开发一个系统, 让大家都能够像现实中邮局和信箱一样,通过电脑网络快速的发信,收信。这样工作效率就能提高了”

小王觉得这很不可思议,简直是天方夜谭, 因为这才80年代初, 个人电脑才刚刚开始兴起。

” 这可能吗? 通过电脑来发信,收信, 听起来很不可思议啊。” 小王问。

“不难不难, 其实我们的电脑已经能联网了, 听说过TCP/IP吧, TCP/IP已经能让两个主机进行通信了,我们只要设计一个基于TCP/IP的系统就行。”

小王了解过TCP/IP,知道这个东西能够在两个机器之间建立一个可靠的连接, 通过这个连接, 两个机器可以互相发送数据。

老周说: “小王你想想,要是你来设计这个电子邮件系统, 模拟一下咱们人类的邮局,你会怎么办?”

小王想了想说: “我们可以在个人电脑上写个程序, 存储每个人的信件, 就像家门口的真实信箱一样, 然后把服务器当成邮局。”

老周问道: 那假设我给你写了信, 先发给了服务器(邮局), 服务器怎么才能发到你的个人信箱呢?

小王想说服务器可以连接个人电脑, 然后把信发过来啊, 但转念一想, 服务器不可能主动的去连接个人电脑, 因为个人电脑可能处于关机状态, 并且ip地址会变化, 服务器没法主动去连接。

“奥,对了,服务器一般很稳定,轻易不关机, 也不会变化” 小王说, “我们不能把邮箱放到个人电脑上, 应该放到服务器上, 每个人开辟一块空间”

“这注意不错, 咱们给每个人的空间起个名称吧, 叫做 用户名@服务器名 , 例如 xiaowang@mshp.com ,如何?”

小王暗暗佩服, 不愧是老司机, 这个 @ 起的太好了, 英文发音 “at” , 意义就是在某某地方, 关键是 @这个字符比较生僻, 很少人会用它做用户名。

小王说: 好,我们可以开发一个程序, 就叫做QuickMail吧, 我可以用QuickMail 来向服务器上的你的邮箱发信 , 你也可以用他从服务器上收信了。

老周说: 不错, 我们还得开发一个服务器端的程序,用来接收收件,存储起来, 我们叫他QuickMailServer 吧, 我们来确定一下邮件里有啥东西吧, 还可以和真实的信件类比。

“那肯定有: 发件人, 收件人, 发件人地址 , 收件人地址,加个邮件标题吧, 还有邮件正文。 ” 小王接着说 “ 奥,不对, 在电脑的世界里, 发件人和发件人地址, 收件认和收件人地址都是相等的, 都是xxx@xx.com”

“所以呢, 收件人, 发件人, 标题,正文, 足够了”

老周说: “电脑世界里, 我们可以轻松的把一封信发给多个人, 所以收件人可以是个列表”

俩人讨论的热火朝天,没想到老板已经站在他们身后多时了。

老板说: “我有些信发给某个人, 还想抄送多个中层干部, 加个抄送人吧,也要支持列表 ; 另外, 有时候我想让某个人例如老周悄悄的看到一封信, 而别人不知道这个信被老周看了, 所以给我加个密送的功能。”

小王心想:还是老板厉害,深谋远虑啊。

老周说:今天先到这里吧, 你再复习下TCP/IP,我们未来编程要用到, 明天咱们确定下协议的事情。

第一天,小王和老周确定了电子邮件的格式: 发件人,收件人,抄送,密送, 标题,正文。

还得到了这样一个设计:

二、协议

周二一大早, 小王就迫不及待的找师傅老周问:” 师傅, 你昨天说到的协议是个啥东西? “

“恩, 协议,简单的说就是双方比如两个电脑之间进行沟通的一种约定。 “

举个例子吧, 你是PC机 (Client),我是服务器(Server), 我们之间可以这么约定:

Client: 服务器你好
Server: 你好
Client: 现在几点了?
Server: 北京时间下午3点40分56秒
Client: 再见
Server: 再见

这就是一种协议 ,假设你说了一句协议之外的话, 例如:

Client: 今天天气如何?

那我就不能识别了,因为不在协议(约定)中。

小王说: “我明白了, 我来设计一个发送邮件的协议吧。 “

两个小时后, 小王拿出了初稿:

“不错, 考虑的挺仔细, 首先考虑到了端口问题,这是TCP要求的 其次发数据那块儿, 我还以为你想不到用什么作为发送数据的结尾呢。“老周说

”不过有个小问题,数据在网络上传输, 中文是不行的,需要进行编码, 把他们变成ASCII码, 也就是ABCDEFabcd1234这些字符“

小王说:”那该怎么办?”

“我听说过一个叫做Base64的东西, 可以把二进制的数据变成小写字母a-z、大写字母A-Z、数字0-9、符号’+’、’/’、’=’ 等字符组成的数据“ 老周说

“这是加密吗 ?” 小王问。

“不是加密, 加密一般是用个密钥把一段明文变成密文, 没有密钥你是没法把密文还原成明文的, 这个Base64只是一种编码而已,规则是已知的, 你可以轻松的把编码过的东西还原。”

老周拿那封信的正文举了个例子, “为了庆祝产品发布, 今晚在海底捞聚餐”经过Base 64编码就会变成这个样子:

5Li65LqG5bqG56Wd5Lqn5ZOB5Y+R5biD77yMIOS7iuaZmuWcqOa1t+W6leaNnuiBmumkkA==

这完全是 ASCII 码了。

(码农翻身注:网上有很多在线的Base64编码,解码网站, 大家可以试验一下)

老周说:要不我们把收信的协议也趁热打铁的设计出来吧。

小王说: “好的”

两个小时后。。。

老周说: “看来你考虑了用户登录的问题, 这个很重要, 自己的邮箱应该是私密的,别人不能访问”

“那我们发信的时候是不是也要做用户登录啊, 如果不是我们系统的用户,就不能发信。”

“应该加上, 如果没有控制, 还可能会出现乱发邮件而无法追踪的问题”

小王说: “好的 , 我完善下,对了师傅, 咱们能不能给这个协议起个名字啊?”

老周说: “发信就叫 “Simple Mail Transfer Protocol” 简称SMTP, 收信叫做 Post Office Protocol , 简称 POP吧。 ”

小王又问: “我想起了个问题, 发信的时候能不能在正文里加上图片,文件这些东西, 这样用起来就更方便了。”

老周: “看来你已经站在用户的角度来思考了, 确实需要加上, 不过我们明天再来设计吧”

(码农翻身注:为了简化起见, 此次设计的协议和真实的SMTP和POP3不完全一致,请大家以标准协议为准)

三、附件

小王回去后想了很久, 怎么才能给在邮件中加上附件呢? 邮件的正文是文本格式的, 但图片,word这些文件是二进制的,完全不同啊?

小王躺在床上翻来覆去很久才睡着, 甚至做了一个Email的梦 :-)

第二天小王找到了师傅老周讲了自己的困惑。

老周说: “我们搞计算机行业的,遇到问题解决方法通常有两个: 1. 增加一个抽象层 2. 分而治之。”

小王不满的心想: 这不等于什么都没有说嘛!

老周笑了:”你想想, 我们把原始问题划分成两个子问题来解决: 1. 如何让邮件正文和附件区分开来。 2. 如何把二进制的数据加入到邮件中。”

小王说: “第一个问题我觉得很简单, 在正文中画一道分隔线不就行了, 上面是正文 ,下面是附件”

“你犯了一个错误,小王, 你把计算机当成人了 , 其实计算机很笨,你需要精确的定义那个分隔线到底是什么, 我们还得精确的告诉计算机,这个邮件分为多个部分, 有些是正文,有些是附件”

小王不好意思的笑了: “的确是, 我们要不这样,先定义一个邮件的内容类型,例如Content-type=plain-text , 那这个邮件就是纯文本的, 如果Content-type=mixed, 就代表是有文本就有附件”

老周想了想说:“这样的话扩展性不好, 我们把Content-type 分为主类型/子类型, 像这样:”

老周说着在白板上画了起来:

Content-type = 主类型/子类型

其中主类型和子类型都可以扩展。

现阶段: 如果主类型是Text , 那子类型可以是 plain, 代表纯文本, 也可以是别的东西, 现在我也不知道, 可以扩展。

如果主类型是 Multipart , 就代表这个文件有多个部分组成, 那子类型可以是mixed, 即多个部分是混合的。

例如:

Content-type=text/plain : 这是个纯文本邮件

Content-type=multipart/mixed : 这是一个由正文和附件混合组成的邮件。

(注: text 除了plain之外,还支持html , multipart 还支持alternative, related , 为了简化,这里不再展开 )

小王说:师傅你考虑的可真是长远啊, 但是这个文本和附件之间的分隔符怎么弄?

老周说: “我们可以让发邮件的客户端,像我们的 Quickmail 自己来选择, 但是选择以后要告诉我们, 我想可以在Content-type后面加个分隔符的属性

Content-type=multipart/mixed;
boundary=”—-=_NextPart_AEDGREGREWGREWGFDSFGSGFDSFTTRFSGGFD_001_0051_01A”;

只要这个boundary的属性和邮件中的数据不冲突就可以 。”

小王说:“我试着设计一个包含附件的正文, 师傅你看看。 ”

老周说: 怪不得老板夸你说你一点就透,果然是啊, 你都能想到给每个附件加个名称和类型了

“还是师傅你考虑的周到,这个Content-type可以随便扩展啊, 想写成啥写成啥。 那第二个问题:附件的内容怎么办? ”

“刚才你写那个邮件正文的base64编码的时候,没有给你启发吗? ”老周反问到

“啊,对了, 这些附件无非就是二进制的数据, 完全可以像处理汉字那样用base64来编码啊! 为了扩展性, 我们要不给每一个部分加一个编码类型的属性? 例如:”

老周满意的说:“没问题,可以的”

四、扩展

小王和老周已经设计了一个收取邮件, 发送邮件的系统, 这个系统还可以支持附件。

在老周的带领下, 小王和其他同事经过几个月的时间把这个系统的客户端和服务器端开发了出来,经过同事的使用, 反响非常的好, 现在公司里每个人都可以快速的收发邮件了,工作效率有了极大的提升。

有一天老板的朋友来参观公司, 看到了这个神奇的系统,也立刻自己的公司部署了一套,包括一个QuickMail服务器和多个客户端, 发现真是好用。

Email 系统就这么一传十,十传百的传开了。

小王所在的MSHP公司仅仅靠出售QuickMail 系统,每年都活的非常滋润。

但是很快大家就遇到了一个问题: Email 在一个公司内运转的良好, 但是两个公司之之间还是没法发送邮件, 商务合作就不顺畅了。

小王想:既然我们的QuickMail 客户端和邮件服务器可以通过SMTP来通信 ,那两个邮件服务器之间是否也也可这么通信呢?

小王找到师傅提出了这个问题。

老周说:当然可以, 比方说吧, 有两个公司, 他们的邮件服务器分别是mailA.com 和 mailB.com , 当userA@mailA.com 给 userB@mailB.com发信的时候, 我们可以这么处理:

1. 用户userA通过SMTP把邮件发给mailA.com 这个邮件服务器

2. mailA.com 发现目标用户userB@mailB.com 并不在 自己的服务器上, 它就把信件暂时放到队列里。

3. mailA.com 从队列中取出邮件, 然后尝试向mailB.com 投递 , 也是通过SMTP , 如果发送失败, 就给userA 发一个投递失败的消息。

4. mailB.com 接收到以后, 存到userB的邮箱里, userB 就可以通过POP3 协议进行收取了

这里唯一做的变化就是让邮件服务器可以暂存邮件, 转发邮件。

于是他们发布了QuickMail 的第2版, 大受欢迎, 很快全世界的邮件服务器都连起来了。

小王和老周由于设计和实现了电子邮件的系统, 在IT界声名鹊起。

五、创业

时间过得很快,90年代初, 有个叫做蒂姆·伯纳斯·李的家伙发明了WWW 互联网, 之前大家只是通过主机相连, 通过telnet , email, bbs 等交流信息, 没想到html ,http以及浏览器出现以后,互联网能够如此的多彩多姿。

小王( 不, 这时候已经是老王了)看到了其中的商机: 既然大家都习惯用浏览器上网, 为什么不把Quickmail 也搬到互联网上去呢?

我可以开发一个基于Web 的邮件系统, 任何想要的人都可以分配一个免费的电子邮件账户 ! 并且在浏览器中使用 !

老王去找老板, 可是老板一直觉得之前的Quickmail 卖的这么好,是公司的主要现金流来源, 搞个免费的Web系统, 那不是革了自己的命吗? 所以一直不支持。

老王感慨于老板的短视, 于是联合老周出来创业了, 有了之前的系统做基础, 他们很快搞出了一套叫做coolmail 的web系统, 在推广上, 他们创造性的采用了一种叫做“病毒营销”的策略:

系统刚开始的时候不接受公开注册申请,而是通过自己的员工等首批成功注册的用户对外发出测试邀请。

即每个用户拥有若干个coolmail账号发放的权限,以邀请的形式发给若干个朋友,幸运者加入后各自也将拥有几个邀请资格,发放给更多的朋友。

试想想,全球每天有多少人接收了coolmail邀请,又有多少人在将他的邀请当作礼物一样发放出去,不需要自己费时费力做推广,业务就像病毒曼延一样由用户自动传播开去,每个参与者都在帮自己宣传。

当然coolmail本身产品质量也是非常过硬的。

coolmail 用户群迅速的爆炸式的增长, 到了1998年, 已经有了几亿的用户, 这引起了想进入互联网的大鳄 microhard 公司的注意, 经过若干轮的谈判, 老王和老周把coolmail 以5亿美金卖了出去, 两人摇身一变成了亿万富豪, 从此就退休了。

后记

2001年, 我在中科院计算所做本科的毕业实习, 做的就是一个基于Web的Email 系统, 虽然很简陋, 但真的学到很多的东西, 尤其是第一次觉得这些协议和系统没什么神秘的,自己也能实现一套出来,那种成就感是无与伦比的。

回想起那时候啃 RFC 英文协议的痛苦, 以及调试 SMTP、POP3客户端程序时的挣扎, 真是感慨万千。

特以此文作为纪念。


打赏支持我写出更多好文章,谢谢!

打赏作者

打赏支持我写出更多好文章,谢谢!

任选一种支付方式

3 3 收藏 2 评论

关于作者:码农老刘

工作15年的前IBM架构师,致力于分享好玩有趣的编程知识 关注微信公共号: 码农翻身, 更多有趣技术文章 个人主页 · 我的文章 · 50 ·   

相关文章

可能感兴趣的话题



直接登录
最新评论
跳到底部
返回顶部