鲜为人知的网络编程(九):理论联系实际,全方位深刻理解DNS

本文原做者:selfboot,博客地址:selfboot.cn,Github地址:github.com/selfboot,感谢原做者的技术分享。html

一、引言

对于 DNS(Domain Name System) 你们确定不陌生,不就是用来将一个网站的域名转换为对应的IP吗。当咱们发现能够上QQ但不能浏览网页时,咱们会想到多是域名服务器挂掉了;当咱们用别人提供的hosts文件浏览到一个“不存在”的网页时,咱们会了解到域名解析系统的脆弱。git

然而关于DNS还有一大堆故事值得咱们去倾听,去思考。程序员

(本文同步发布于:http://www.52im.net/thread-27...github

二、系列文章

本文是系列文章中的第9篇,本系列文章的大纲以下:面试

《鲜为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)》
《鲜为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)》
《鲜为人知的网络编程(三):关闭TCP链接时为何会TIME_WAIT、CLOSE_WAIT》
《鲜为人知的网络编程(四):深刻研究分析TCP的异常关闭》
《鲜为人知的网络编程(五):UDP的链接性和负载均衡》
《鲜为人知的网络编程(六):深刻地理解UDP协议并用好它》
《鲜为人知的网络编程(七):如何让不可靠的UDP变的可靠?》
《鲜为人知的网络编程(八):从数据传输层深度解密HTTP》
《鲜为人知的网络编程(九):理论联系实际,全方位深刻理解DNS》(本文)数据库

三、参考资料

《DNS cache poisoning》
《DNS Spoofing vs DNS Cache Poisoning》
《Reset the DNS cache in OS X》
《人为网络故障》
《DNS欺骗原理及工做工程分析》
《全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等》
《美图App的移动端DNS优化实践:HTTPS请求耗时减少近半》
《百度APP移动端网络深度优化实践分享(一):DNS优化篇》编程

四、DNS 源起

要想访问网络上的一台计算机,咱们必需要知道它的IP地址,可是这些地址(好比243.185.187.39)只是一串数字,没有规律,所以咱们很难记住。而且若是一台计算机变动IP后,它必须通知全部的人。缓存

显然,直接使用IP地址是一个愚蠢的方案。因而人们想出了一个替代的方法,即为每一台计算机起一个名字,而后创建计算机名字到地址的一个映射关系。咱们访问计算机的名字,剩下的名字到地址的转换过程则由计算机自动完成。安全

4.1 hosts映射
早期,名字到地址的转换过程十分简单。每台计算机保存一个hosts文件,里面列出全部计算机名字和对应的IP地址,而后按期从一个维护此文件的站点更新里面的记录。当咱们访问某个计算机名字时,先在hosts文件找到对应的IP,而后就能够创建链接。服务器

图片描述
▲ hosts 管理主机

早期的 ARPANET 就是这样作的,可是随着网络规模的扩大,这种方法渐渐吃不消了。

主要有如下三个缘由:

1)hosts文件变得很是大;
2)主机名字会冲突;
3)集中的维护站点会不堪重负(须要给几百万机器提供hosts文件,想一想就可怕)。

4.2 域名系统

为了解决上面的问题,1983年Paul Mockapetris提出了域名系统(DNS, Domain Name System),这是一种层次的、基于域的命名方案,而且用一个分布式数据库系统加以实现。当咱们须要访问一个域名(其实就是前面说的计算机的名字)时,应用程序会向DNS服务器发起一个DNS请求,DNS服务器返回该域名对应的IP地址。

人物介绍:保罗·莫卡派乔斯(Paul V. Mockapetris):
图片描述
保罗·莫卡派乔斯是发明Domain Name System (DNS域名系统)体系结构的RFCs882和883技术创始人和计算机科学家,同时也是现代Internet的奠定者之一。他在1983年的第882和在南加州大学里资讯科学研究院所提出的883号因特网标准草案中提出DNS的架构。他发现了早期因特网,包括阿帕网中基于单个主机单一层面上的域名-IP地址转换的缺陷,并提议将其改进为分布式和动态的数据库域名系统,也就是咱们今天所用的域名系统的雏形。在2005年,他得到了ACM(美国计算机协会)数据通讯专业组终身成就奖。

经过下面三种手段解决了上面的问题:

1)用户计算机上并无存储全部的名字到IP的映射,这样避免了hosts文件过于庞大(如今各操做系统中hosts文件默认都是空的);
2)规定了域名的命名规则,保证主机名字不会重复;
3)DNS服务器再也不是单一的一台机器,而是一个层次的、合理组织的服务器集群。

这样访问一个域名的过程能够简化为下图:
图片描述
▲ 域名hosts解析过程

五、DNS 协议

那么如何具体实现这个所谓的域名系统呢,要知道管理一个超大型而且不断变化的域名到IP的映射集合可不是一个简单的事,何况还要去应付成千上万的DNS查询请求。人们最终想出了一套不错的协议,规定如何来实现这个系统,下面咱们一块儿来看看吧。

5.1 域名空间

首先咱们须要制定一套命名规则,防止域名出现重复。DNS关于域名的规则和咱们生活中的快递系统相似,使用层次的地址结构。快递系统中要给某人邮寄物品,地址多是这样:中国、广东省、广州市、番禺区、中山西路12号 XXX。而一个域名看起来则是这样的groups.google.com(为何不是com.google.groups?我猜可能和老外写地址的习惯有关)。

对于Internet来讲,域名层次结构的顶级(至关于国际快递地址中的国家部分)由ICANN(互联网名称与数字地址分配机构)负责管理。目前,已经有超过250个顶级域名,每一个顶级域名能够进一步划为一些子域(二级域名),这些子域可被再次划分(三级域名),依此类推。

全部这些域名能够组织成一棵树,以下图所示:
图片描述
▲ 域名空间树

5.2域名资源记录

DNS设计之初是用来创建域名到IP地址的映射,理论上对于每个域名咱们只须要在域名服务器上保存一条记录便可。

这里的记录通常叫做域名资源记录,它是一个五元组,能够用如下格式表示:

Domain_name Time_to_live Class Type Value

其中:

1)Domain_name: 指出这条记录适用于哪一个域名;
2)Time_to_live: 用来代表记录的生存周期,也就是说最多能够缓存该记录多长时间(后面会讲到缓存机制);
3)Class: 通常老是IN;
4)Type: 记录的类型;
5)Value: 记录的值,若是是A记录,则value是一个IPv4地址。

咱们看到域名资源记录有一个Type字段,用来代表记录的类型。这是为何呢?由于对于一个域名来讲,一般并不是只记录其IP地址,还可能须要一些其余种类的记录。

一些常见的记录类型以下:
图片描述

关于这些域名资源记录的实例咱们将在文章后半部分看到。

5.3 域名服务器

咱们知道不能只用一台域名服务器来响应全部的DNS查询,由于没有一台机器可以给全球的用户提供查询服务,计算能力、存储、带宽都不容许。只能合理组织一个域名服务器集群,使他们协同工做,共同提供域名解析服务。接下来首先要面对的一个问题是:如何合理地将全部的域名资源记录存储到不一样的域名服务器上。

前面说过域名的名字空间能够组织为一棵树,这里咱们能够进一步将其划分为不重叠的区域(DNS zone)。

针对上图的域名空间,一种可能的域名划分以下图:
图片描述
▲ 域名划分

而后将每一个区域与多个域名服务器(其中一个是master,其余slave服务器则用来提供数据备份、加快解析速度、保证服务可用性)关联起来,称这些域名服务器为该区域的权威域名服务器(Authoritative Name Servers )。

它保存两类域名资源记录:

1)该区域内全部域名的域名资源记录;
2)父区域和子区域的域名服务器对应的域名资源记录(主要是NS记录)。

这样,全部的域名资源记录都保存在多个域名服务器中,而且全部的域名服务器也组成了一个层次的索引结构,便于咱们后面进行域名解析。下面以一个简化的域名空间为例子,说明域名资源记录是如何保存在域名服务器中的。

以下图a:
图片描述
▲ 域名服务器

图中域名空间划分为A, B, C, D, E, F, G七个DNS区域,每一个DNS区域都有多个权威域名服务器,这些域名服务器里面保存了许多域名解析记录。对于上图的NDS区域E来讲,它的权威域名服务器里面保存的记录如图中表格所示。

仔细观察上图你可能会发现区域A、B并无父区域,他们之间并无一条路径连在一块儿。这将致使一个很麻烦的问题,那就是区域A的权威域名服务器可能根本不知道区域B的存在。认识到这一点后,你可能会想出一个很天然的解决方案,就是在A中记录B域名服务器的地址,同时在B中记录A的,这样它们两个就联系起来了。可是考虑到咱们有超过250个顶级域名,这样作并非很恰当。

而咱们使用的域名系统则采用了一种更加聪明的方法,那就是引入根域名服务器,它保存了全部顶级区域的权威域名服务器记录。如今经过根域名服务器,咱们能够找到全部的顶级区域的权威域名服务器,而后就能够往下一级一级找下去了。

下图为全球根域名服务器的分布图:
图片描述
(本图的清晰大图,来自:http://www.root-servers.org/

如今为止,咱们的权威域名服务器和根域名服务器其实组成了一个树,树根为根域名服务器,下面每一个节点都是一个区域的权威域名服务器,对于图a中各个DNS区域的权威域名服务器,它们组成了下面这棵树(实际中,一个权威域名服务器可能保存有多个DNS区域的记录,所以权威域名服务器之间的联系并不构成一棵树。这部分的详细内容能够参考RFC 1034: 4. NAME SERVERS。

下面为了容易理解,将其简化为一棵树):
图片描述

5.4 域名解析

咱们已经有了一个域名服务器集群,该集群合理地保存了域名空间和域名资源记录的对应关系。如今咱们要作的就是发送一个DNS请求给域名服务器,而后坐等它返回正确的域名资源记录,这个过程叫做域名解析。

严格来讲,域名解析的过程最先要追溯到创建网络链接。由于每当链接上网络以后,计算机会自动得到一个默认的DNS服务器,固然你也能够用本身信任的DNS服务器,好比8.8.8.8(DNS服务器也有信任不信任之分,是的,实践篇会讲到),咱们把这个域名服务器也叫做本地域名服务器。接下来当咱们须要知道一个域名对应的资源记录时,会向本地域名服务器发起请求,若是该域名刚好在本地域名服务器所辖属的域名区域(DNS zone)内,那么能够直接返回记录。

若是在本地域名服务器没有发现该域名的资源记录,就须要在整个域名空间搜索该域名。而整个域名空间的资源记录存储在一个分层的、树状联系的一系列域名服务器上,因此本地域名服务器首先要从根域名服务器开始往下搜索。这里有一个问题就是:本地域名服务器如何找到根域名服务器在哪里呢?其实域名服务器启动的时候,就会加载一个配置文件,里面保存了根域名服务器的NS记录(要知道根域名服务器地址通常很是稳定,不会轻易改变,而且数量不多,因此这个配置文件会很小)。找到根域名服务器以后,就能够一级一级地往下查找啦。

仍然以咱们的图a为例,如今假设区域E内的某个用户想访问math.sysu.edu.cn,那么请求的过程以下:
图片描述

用语言简单描述以下:

1)用户:喂,本地域名服务器,告诉我math.sysu.edu.cn的地址;
2)本地域名服务器:哎呀,我不知道啊,不在个人辖区,容我去问问老大哥吧。root老大,能告诉我math.sysu.edu.cn的地址吗;
3)根域名服务器:忙着呢,你去问B(.cn);
4)本地域名服务器:喂,B,告诉我math.sysu.edu.cn的地址;
5)B:你去问D(.edu.cn);
6)本地域名服务器:喂,D,告诉我math.sysu.edu.cn的地址;
7)D:你去问F(sysu.edu.cn);
8)本地域名服务器:喂,F,告诉我math.sysu.edu.cn的地址;
9)F:容老衲看看,哎呀,找到了,是X.X.X.X;
10)本地域名服务器:踏破铁鞋终于找到啦,喂用户,出来啊,我找到了,是X.X.X.X。

仔细想一想,这和咱们邮寄快递实在是一模一样啊,假设你从美国邮东西到广州市番禺区,首先快递送到中国(不过这里没有一个相似根域名服务器的中转站而已),而后往下到广东省,接下来是广州市,再往下是番禺了。

上面的是本地域名服务器的迭代解析过程,其实也能够递归查询,这里就不说了,道理差很少。

六、缓存机制

如今整个域名系统已经能够为咱们提供域名解析服务了,当咱们输入域名,计算机发送DNS请求,而后DNS服务器返回给咱们解析的结果,一切看起来很完美。然而是否是能够更完美呢?

回顾一下平时浏览网站的状况,咱们会发现两个比较有意思的结论:

1)80%的时间咱们都在看那些20%的网站,这就是大名鼎鼎的 80/20 Rule;
2)咱们会在一个网站的不一样网页之间跳转,也就是不断地访问同一个域名,相似程序访问的局部性原理。

这两条结论很容易让咱们联想到缓存机制。若是咱们将已经访问过的那些域名的解析结果缓存在本身的计算机上,那么下次访问的时候能够直接读取结果,不用再次重复DNS查询过程,给本身和域名服务器都节省了麻烦。

固然,这样作的一个前提是要缓存的解析结果不会频繁更改,也就是说我十分钟后解析一个域名的结果和如今解析的结果是同样的。对大多数域名来讲,这都是一个不争的事实。可是不免有一些“善变”的域名,他们可能会频繁更改本身的解析结果。为了使缓存机制适应这两类状况,咱们在域名资源记录里面添加一个 Time_to_live 字段,代表这条记录最多能够缓存多久。对于那些“稳如泰山”的域名,给一个比较大的值,而那些“朝秦暮楚”的域名,则能够给定一个小的值。

咱们既然能够在本机利用缓存,那么可不能够在域名服务器上也利用缓存机制呢,答案固然是能够的。由于对于域名服务器来讲,上面的两条有意思的结论仍然有效。因此,域名服务器能够将那些访问过的域名资源记录缓存,用户再次发起请求时,能够直接返回缓存结果,不用去迭代或者递归解析。

关于DNS理论部分,更多内容还能够参考这两个文本:《RFC 1034: Domain Names - Concepts and Facilities》。

七、文章并无结束

在上面的理论内容章节里,咱们基本了解了DNS的整个协议原理。

可是可能还会有着下面的疑问:

1)为何我想申请的域名都没了?
2)DNS 域名还要备案,这是为何啊?
3)如何将刚申请的域名绑定到本身的网站呢?
4)怎么才能看到那些在背后默默给我解析的域名服务器呢?
5)他们说用一个什么文件就能够访问好多好多不存在的网站,是真的吗?
6)可信任的域名服务器是怎么一回事,难道有些域名服务器会作坏事?
7)怎么知道我如今用的域名服务器有没有使坏呢?
8)……

我不许备一个一个地去回答这些问题,不过相信我,读完下面的内容,对于上面问题的答案你会有一个清晰的认识,而且能够解决其余各类各样关于 DNS 方面的问题。

八、域名注册、绑定

首先明确一点,每一个人均可以去注册域名。大多数时候咱们但愿去注册一个顶级域名(好比52im.net、google.com等),那些二级域名毕竟不够好记(好比github托管博客的域名:username.github.io)。有的顶级域名(好比.tk域名)提供免费的一年域名试用,不过绝大多时候仍是要为本身的域名付费的(通常是按年付费,也不是很贵)。要想去注册域名,首先得找到域名注册商,国内的比较著名的有万网等(PS:万网已被阿埋里收购了),国外的有godaddy等。相信注册过域名的人都知道绝大多数咱们能想到的本身喜欢的域名都已名花有主了,只剩那些不是那么惹人关注的域名供咱们选择。因此,注册域名时,发现本身每想到一个域名都显示被人注册后,那太正常不过了,说明你的品味比较正常。

这里一点我的建议,选中一个域名后不要轻易去改了,由于换域名成本挺高的(我猜如今就算给淘宝一千万,它也不会换另成一个域名吧)。因此,最好不要去用免费的域名,由于指不定啥时候就不让你用了。你应该相信这么一个观点:天下没有免费的午饭。拓展一下就是,掏钱买服务,内心踏实。

接下来你可能会但愿将本身的站点或者博客挂在本身选中的域名下,这其实很简单,只须要找到一个提供域名解析的服务商,而后填写相应的域名解析记录。大多时候,你注册域名的服务商都会免费提供域名解析服务。

现实中,大部分人可能会拥有我的博客,之前咱们都是依赖一个博客平台(如CSDN),或者是买一台VPS托管本身的博客。不过自从Github推出了Blog服务,好多程序员都转而将博客托管在上面。Github Blog支持绑定我的域名,并提供了详细的绑定文档:Adding a CNAME file to your repository。假设你的博客已经能够经过 username.github.io 访问,接下来只须要用 CNAME 告诉Github你的博客绑定了哪一个域名(好比说是selfboot.cn),而后在域名解析商那里添加解析记录便可。

下图是我我的博客在DNSpod的解析记录:
图片描述
▲ 域名解析记录

如今当咱们访问 selfboot.cn 时,DNSpod就会将请求解析到 Github 提供的 IP 地址上。以后 Github 上面的博客托管服务器在全部用户的 CNAME 记录中,找到本次请求的域名对应的博客项目地址,好比说是 xuelangZF.github.io,而后返回博客内容。

九、域名解析

咱们都知道一个域名的解析过程当中,可能会有多台域名服务器给咱们帮助,那么咱们怎么能看到这些背后的功臣呢?先介绍两个经常使用的关于DNS的命令。

9.1 dig和nslookup命令

dig(Domain Information Groper), 是 UNIX/BSD 系统自带的 DNS 诊断工具,使用十分灵活、方便。

查询 selfboot.cn 的A记录,并返回简短的结果:
$ dig selfboot.cn -t A +short
192.30.252.153
192.30.252.154

用 dig 还能够查询某一 ip 对应的域名,以下:
$ dig -x 192.30.252.153 +short
pages.github.com.

这里返回的是pages.github.com,由于当你访问博客地址 selfboot.cn 时,实际上是Github的pages 服务器(域名是:pages.github.com)在后台返回该博客内容的(根据 CNAME 肯定返回哪一个博客)。

nslookup 也是一个 DNS 诊断工具,几乎全部平台都自带该工具,使用也很简答,能够用 man 查询手册。

9.2 解析路径查询

接下来用 dig 命令查看从根域名到指定域名中间可能通过的全部域名服务器,使用 +trace 选项便可。
dig selfboot.cn +trace @8.8.8.8
; <<>> DiG 9.8.3-P1 <<>> selfboot.cn +trace @8.8.8.8
;; global options: +cmd
. 474418 IN NS j.root-servers.net.
. 474418 IN NS g.root-servers.net.
......
. 474418 IN NS l.root-servers.net.
. 474418 IN NS m.root-servers.net.
;; Received 496 bytes from 8.8.8.8#53(8.8.8.8) in 12 ms
cn. 172800 IN NS a.dns.cn.
......
cn. 172800 IN NS e.dns.cn.
cn. 172800 IN NS ns.cernet.net.
;; Received 292 bytes from 2001:500:1::803f:235#53(2001:500:1::803f:235) in 382 ms
selfboot.cn. 86400 IN NS f1g1ns2.dnspod.net.
selfboot.cn. 86400 IN NS f1g1ns1.dnspod.net.
;; Received 83 bytes from 203.119.25.1#53(203.119.25.1) in 816 ms
selfboot.cn. 14400 IN A 192.30.252.153
selfboot.cn. 14400 IN A 192.30.252.154
selfboot.cn. 600 IN NS f1g1ns1.dnspod.net.
selfboot.cn. 600 IN NS f1g1ns2.dnspod.net.
;; Received 125 bytes from 115.236.137.40#53(115.236.137.40) in 31 ms

能够看到最开始是13台顶级域名服务器的NS记录(中间省去一些记录减小行数,方便观察更清楚),接下来是顶级域名 cn. 的权威域名服务器(省略一些输出),而后是 selfboot.cn 的 NS 记录,即 DNSpod 的两条 NS 记录,最后从 f1g1ns2.dnspod.net 找到 selfboot.cn 的 A 记录。

seveas 提供了一个可视化的路径查询工具:dnsgraph,能够在线绘制跟域名到指定域名的全部可能路径。

固然,实际查询过程当中,大多时候咱们在本地缓存或者本地域名服务器缓存就能直接找到须要的域名记录,不须要每次都向根域名服务器发起请求,而后重复迭代或者递归查询过程。

十、DNS目前存在的缺陷

域名系统设计的很理想很美好,然而仍有一些小的瑕疵,可能会给咱们带来些许困扰。

10.1 域名抢注

首先,有些域名对注册人没有限制,而另一些域名则对谁能够获得一个域名空间中的名字有限制。好比pro域名是分配给合适的专业人员,但问题是谁才是专业的呢?显然医生、工程师是专业人员,但理发师、管道工呢?

此外,域名也能够被倒卖。黄牛们会批量注册大量域名(听说com域名下几乎每个普通词都被人尝试注册了域名),而后转身就以高价转卖给那些对该域名感兴趣的人,这就是所谓的域名抢注。因此,如今你想注册一个符合本身网站特色的域名是很难的。

这个问题其实还不算严重,更要命的是下面两个问题。

10.2 DNS 劫持

咱们知道一个域名服务器对其区域内的用户解析请求负责,可是并无一个机制去监督它有没有真地负责。也就是说域名服务器的权力并无被关在笼子里,因此它既能够认真地“为人民服务”,也能够混淆是非。因而有些流氓的域名服务器故意更改一些域名的解析结果,将用户引向一个错误的目标地址。这就叫做 DNS 劫持,主要用来阻止用户访问某些特定的网站,或者是将用户引导到广告页面。

图片描述
▲ DNS 劫持原理

下面验证下我所用的域名服务器有没有干这种坏事,只须要一条简单的命令便可:
➜ ~ nslookup google.com
Server: 10.8.4.4
Address: 10.8.4.4#53
Non-authoritative answer:
Name: google.com
Address: 120.196.0.5

个人DNS服务器地址为10.8.4.4,他告诉我google.com的地址是120.196.0.5,我才不信呢。因而用whois 120.196.0.5一看,果然不是Google的地址。针对DNS劫持,咱们能够简单地更换域名服务器,比较靠谱的一个是Google提供的8.8.8.8。下面用 8.8.8.8 来解析一下 www.google.com 就能看到正确的地址了。

$ nslookup [url=http://www.google.com]www.google.com[/url] 8.8.8.8
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
Name: [url=http://www.google.com]www.google.com[/url]
Address: 216.58.221.68

更多关于DNS劫持这方面的内容,能够详见:《全面了解移动端DNS域名劫持等杂症:技术原理、问题根源、解决方案等》。

10.3 DNS 欺骗

DNS 劫持经过简单的切换域名服务器就能够绕过,不过一旦你赶上了 DNS 欺骗,就没法简单地绕过了。下面咱们用不一样的域名服务器来查看 fb 的 IP 地址,结果都返回了同一个地址,看起来好像是真的同样,不过也仅仅是看起来而已。

$ nslookup facebook.com
Server: 10.8.4.4
Address: 10.8.4.4#53
Non-authoritative answer:
Name: facebook.com
Address: 159.106.121.75
$ nslookup facebook.com 8.8.8.8
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
Name: facebook.com
Address: 159.106.121.75

这个地址并非 fb 的服务器地址(能够在 ViewDNS 查询全部域名真实的域名资源记录,ViewDNS 是个很好玩的网站,里面有许多有意思的工具)。其实我Google了一下这个地址,居然发现了一篇不错的 译文 ,看来这个地址早在 2011 年就有了特殊的含义(英文原文是相关阅读第一个)。

DNS 欺骗简单来讲就是用一个假的 DNS 应答来欺骗用户计算机,让其相信这个假的地址,而且抛弃真正的 DNS 应答。在一台主机发出 DNS 请求后,它就开始等待应答,若是此时有一个看起来正确(拥有和DNS请求同样的序列号)的应答包,它就会信觉得真,而且丢弃稍晚一点到达的应答。

图片描述
▲ DNS欺骗原理

实施 DNS 欺骗的关键在于伪造一个有特定序列号的应答包,而且让其抢先一步到达发起请求的主机。这对于我的来讲还有点难度,可是对于拥有骨干网节点的组织来讲,实在是易如反掌,因此这么多网站都已沦陷。不过使用网上流传的那些 hosts文件,就能够在本机缓存许多网站的ip地址,进而能够和部分网站通讯。可是经过hosts文件并不能彻底 Cross the Great FireWall,由于人家还有不少其余手段。

附录:更多网络编程基础资料

《TCP/IP详解 - 第11章·UDP:用户数据报协议》
《TCP/IP详解 - 第17章·TCP:传输控制协议》
《TCP/IP详解 - 第18章·TCP链接的创建与终止》
《TCP/IP详解 - 第21章·TCP的超时与重传》
《技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)》
《通俗易懂-深刻理解TCP协议(上):理论基础》
《通俗易懂-深刻理解TCP协议(下):RTT、滑动窗口、拥塞处理》
《理论经典:TCP协议的3次握手与4次挥手过程详解》
《理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程》
《计算机网络通信协议关系图(中文珍藏版)》
《UDP中一个包的大小最大能多大?》
《P2P技术详解(一):NAT详解——详细原理、P2P简介》
《P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解》
《P2P技术详解(三):P2P技术之STUN、TURN、ICE详解》
《通俗易懂:快速理解P2P技术中的NAT穿透原理》
《高性能网络编程(一):单台服务器并发TCP链接数到底能够有多少》
《高性能网络编程(二):上一个10年,著名的C10K并发链接问题》
《高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了》
《高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索》
《高性能网络编程(五):一文读懂高性能网络编程中的I/O模型》
《高性能网络编程(六):一文读懂高性能网络编程中的线程模型》
《技术扫盲:新一代基于UDP的低延时网络传输层协议——QUIC详解》
《让互联网更快:新一代QUIC协议在腾讯的技术实践分享》
《现代移动端网络短链接的优化手段总结:请求速度、弱网适应、安全保障》
《聊聊iOS中网络编程长链接的那些事》
《移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”》
《移动端IM开发者必读(二):史上最全移动弱网络优化方法总结》
《IPv6技术详解:基本概念、应用现状、技术实践(上篇)》
《IPv6技术详解:基本概念、应用现状、技术实践(下篇)》
《从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路》
《以网游服务端的网络接入层设计为例,理解实时通讯的技术挑战》
《迈向高阶:优秀Android程序员必知必会的网络基础》
《Android程序员必知必会的网络通讯传输层协议——UDP和TCP》
《IM开发者的零基础通讯技术入门(一):通讯交换技术的百年发展史(上)》
《IM开发者的零基础通讯技术入门(二):通讯交换技术的百年发展史(下)》
《IM开发者的零基础通讯技术入门(三):国人通讯方式的百年变迁》
《IM开发者的零基础通讯技术入门(四):手机的演进,史上最全移动终端发展史》
《IM开发者的零基础通讯技术入门(五):1G到5G,30年移动通讯技术演进史》
《IM开发者的零基础通讯技术入门(六):移动终端的接头人——“基站”技术》
《IM开发者的零基础通讯技术入门(七):移动终端的千里马——“电磁波”》
《IM开发者的零基础通讯技术入门(八):零基础,史上最强“天线”原理扫盲》
《IM开发者的零基础通讯技术入门(九):无线通讯网络的中枢——“核心网”》
《IM开发者的零基础通讯技术入门(十):零基础,史上最强5G技术扫盲》
《IM开发者的零基础通讯技术入门(十一):为何WiFi信号差?一文即懂!》
《IM开发者的零基础通讯技术入门(十二):上网卡顿?网络掉线?一文即懂!》
《IM开发者的零基础通讯技术入门(十三):为何手机信号差?一文即懂!》
《IM开发者的零基础通讯技术入门(十四):高铁上无线上网有多难?一文即懂!》
《IM开发者的零基础通讯技术入门(十五):理解定位技术,一篇就够》
《技术大牛陈硕的分享:由浅入深,网络编程学习经验干货总结》
《可能会搞砸你的面试:你知道一个TCP链接上能发起多少个HTTP请求吗?》
《知乎技术分享:知乎千万级并发的高性能长链接网关技术实践》

更多同类文章 ……

(本文同步发布于:http://www.52im.net/thread-27...

相关文章
相关标签/搜索