- 我是一个线程(修订版)
- 我是一个 Java class
- Javascript:一个屌丝的逆袭
- Java : 一个帝国的诞生
- JSP 一个装配工的没落
- TCP/IP 之 大明王朝邮差
- TCP/IP 之大明内阁
- TCP/IP 之蓟辽督师
- CPU 阿甘
- CPU 阿甘之烦恼
- CPU 阿甘:函数调用的秘密
- 我是一个网卡
- 我是一个路由器
- 我是一个进程
- 我是一块硬盘(上)
- 我是一块硬盘(下)
- 我是一个键盘
- 张大胖的 socket
- 张大胖学递归
- 学习面向对象的令狐冲
- 张大胖学数据库
- 数据库村的旺财和小强
- 小李的数据库之旅(上)
- 小李的数据库之旅(下)
- 漫画:什么是机器学习?
- 那些烦人的同步和互斥问题
- IE 为什么把火狐和 Chrome 给打伤了?
- 对浏览器村的第二次采访
- 节约标兵 IE 的自述
- EMail 诞生记
- Email 诞生记(下)
- Http 历险记(上)
- Http 历险记(下)-- Struts 的秘密
- 动物王国的面向对象
- 冯·诺伊曼计算机的诞生
- Http Server : 一个差生的逆袭
- 张大胖的加法器
- 从 1 加到 100:一道简单的数学题挑战下你的大脑
- 编程语言
- Javascript:一个屌丝的逆袭
- 计算机语言之战
- 我和编程语言的爱恨情仇(上)
- 我和编程语言的爱恨情仇(下)
- Android 为什么选择了 Java
- iOS 为什么选择了 Object-C?
- Basic : 一个老兵的自述
- Node.js : 我只需要一个店小二
- 命令式编程 vs 声明式编程
- 编译还是解释?
- 程序人生
- “架构师"小赵
- 师兄说
- 师姐说
- 小王的架构师之路
- 小李的版本管理系统
- 小超穿越记
- 小李的 Build 之路(上)
- 小李的 Build 之路(下)
- 张大胖改 Bug
- 我的编程之路--大学趣事
- 码农小王的一天
- 小李在外企
- 张大胖的需求估算
- 从厨师到码农
- 聊一聊那些神一样的程序员们(上)
- 聊一聊那些神一样的程序员们(中)
- 聊一聊那些神一样的程序员们(下)
- 谁是互联网之父?
- 一个价值百万的创业教训
- 让自己与众不同 - 提升工作的价值
- 看看你的“易燃性”
- 从无聊的工作中寻找价值
- 什么样的学生适合报考计算机?
- 谈谈程序员的职业方向(上)
- 谈谈程序员的职业方向(中)
- 谈谈程序员的职业方向(下)
- 谈谈培训班的作用
- 码农需要知道的“潜规则”
- 学习编程的加速度
- 码农在工作中的必备能力
- 码农和英语
- 老司机经验
- 假如时光能够倒流, 我会这么学习 Java
- 假如我是计算机系老师
- 学会编程, 而不是学会 Java
- 从增删改查中突围
- 抽象:程序员必备的能力
- 懒就一个字
- 编程的自学方法
- 小王买房记
- 从一道面试题谈谈一线码农应该具备的基本素质
- 想写框架的看过来
- 苹果手机变砖头以后
- 如何快速的学习一门技术?
- 唯一不变的是变化: 谈谈微信应用号
- 什么是企业应用?
- 勿以浮沙筑高台
- 为什么敏捷开发难于成功?
- localhost vs 127.0.0.1
- GitHub/Stackoverflow 找工作时有什么用?
- 动词 or 名词 :这是一个问题
- 如何选择入行语言
- 有时候,沉默是金
- 零 Bug 的代码是怎么炼成的?
- 浮点数为什么不精确?
- 文章错误大全
- Open Source--不要为了开源而开源
- 一不留神,代码就腐化了
- 先做个“键盘侠”, 再来写程序
- 不加断点调试的程序员是好程序员
- 码农必备技能:烂代码的处理之道(上)
- 码农必备技能:烂代码的处理之道(下)
- 学习数据结构有用吗?
- 从现在开始,丰富你的简历
- 那些永不过时的书,你看过几本吗?
- 学好编程必备的一个品质你知道吗?
- 你最爱的 Java
- 搞懂了这几点,你就学会了 Web 编程
- Spring 的本质系列(1) -- 依赖注入
- Spring 本质系列(2)-AOP
- 三层架构和 MVC 那点事儿
- Java 帝国之拨云见日识回调
- 小张的 Duck Typing
- JDBC 的诞生
- JDBC 后传
- 一个不安分的 JDBC 驱动
- Java 帝国之 Java bean (上)
- Java 帝国之 Java bean(下)
- Java 帝国之函数式编程
- Java 帝国之函数式编程(下)
- 关于 Java 初学者需要知道的 10 件事
- JUnit 你不知道的那些事儿
- 圣诞礼物:Java EE 的历史
- Java EE 读书指南
- 给小白的 Java EE 指南
- 给小白的 Java EE 指南(2)
- 给小白的 Java EE 生存指南(3) : XML
- 给小白的 Java EE 生存指南(4) : 一只叫 Tom 的猫
- 给小白的 Java EE 指南(5) : AJAX
- 给小白的 Java EE 生存指南(6) :Java 反射
- 闲聊
- "饿了么"初体验
- 来自大脑的控诉
- 一个高中生是怎么玩自媒体的?
- 尝试 分答
- 到底应不应该上培训班?
- 自学编程中遇到问题怎么办?
- 据说 99%的初级程序员看完后都不迷茫了
- 一行代码引发的“血案”
- 对一个死锁问题的思考
- 通过外包进入名企
- 请开往十年前的今天
- 为什么自学中最好有个师傅指导一下?
- 这个网站值得你花时间投入
- 为什么你无法坚持自学编程?
Email 诞生记(下)
上次在《Email 诞生记 》说到小王和老周设计了电子邮件的系统, 但是不能支持附件 -- 这也是本文要解决的重点。 3 附件 小王回去后想了很久, 怎么才能给在邮件中加上附件呢? 邮件的正文是文本格式的, 但图片,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 的属性和邮件中的数据不冲突就可以 。”
小王说:“我试着设计一个包含附件的正文, 师傅你看看。 ”
//定义这是一个混合的邮件, 每个部分的分隔符由 boundary 定义。 为了便于阅读, 我把这个 boundary 故意写的很简单, 实际复杂的多
Content-type=multipart/mixed; boundary="--A001_0051_01A";
//以分隔符来开始邮件正文 ----A001_0051_01A
//这是“为了庆祝产品发布, 今晚在海底捞聚餐”的 base64 编码的结果
5Li65LqG5bqG56Wd5Lqn5ZOB5Y+R5biD77yMIOS7iuaZmuWcqOa1t+W6leaNnuiBmumkkA==
----A001_0051_01A Content-type:audio/wav name:"fly.wav" <这里是附件 1 的数据>
----A001_0051_01A Content-type: image/jpg name:"sky.jpg"
<这里是附件 2 的数据>
//整个邮件结束的标记
----A001_0051_01A
老周说: 怪不得老板夸你说你一点就透,果然是啊, 你都能想到给每个附件加个名称和类型了
“还是师傅你考虑的周到,这个 Content-type 可以随便扩展啊, 想写成啥写成啥。 那第二个问题:附件的内容怎么办? ”
“刚才你写那个邮件正文的 base64 编码的时候,没有给你启发吗? ”老周反问到
“啊,对了, 这些附件无非就是二进制的数据, 完全可以像处理汉字那样用 base64 来编码啊! 为了扩展性, 我们要不给每一个部分加一个编码类型的属性? 例如:” Content-type: image/jpg name:"sky.jpg" encoding: base64
老周满意的说:“没问题,可以的” 4 扩展 小王和老周已经设计了一个收取邮件, 发送邮件的系统, 这个系统还可以支持附件。 在老周的带领下, 小王和其他同事经过几个月的时间把这个系统的客户端和服务器端开发了出来,经过同事的使用, 反响非常的好, 现在公司里每个人都可以快速的收发邮件了,工作效率有了极大的提升。 有一天老板的朋友来参观公司, 看到了这个神奇的系统,也立刻自己的公司部署了一套,包括一个 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 界声名鹊起。 5 创业 时间过得很快,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 客户端程序时的挣扎, 真是感慨万千。
特以此文作为纪念。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论