《网络是怎么样连接的》读书笔记 - 汇总篇

2022-07-01 15:08:58 浏览数 (2)

《网络是怎么样连接的》读书笔记 - 汇总篇

引言

其实就是把之前的内容汇总到一个文章方便阅读。为了节省大家的时间,建议挑自己感兴趣的内容看,而不是从上往下看,建议看一切文字材料都保持这样的习惯。

资源链接

《网络是怎么样连接的》电子书资源,包含PDF和EPUB。

链接:https://pan.baidu.com/s/15IGzN4xtPgCoX1mrycMUCA?pwd=f5sy

提取码:f5sy

历史文章汇总

必看章节:

[《网络是怎么样连接的》读书笔记 - 认识网络基础概念(一)]

[《网络是怎么样连接的》读书笔记 - Tcp-IP连接(二)]

[《网络是怎么样连接的》读书笔记 - 集线器、路由器和路由器(三)]

选看章节:

[《网络是怎么样连接的》读书笔记 - 服务器端的局域网中(四)]

[《网络是怎么样连接的》读书笔记 - WEB服务端请求和响应(五)]

非必看章节:

[《网络是怎么样连接的》读书笔记 - FTTH]

[《网络是怎么样连接的》读书笔记 - ADSL]

《网络是怎么样连接的》读书笔记 - 认识网络基础概念(一)

本章重点

  1. 关于互联网的一些历史补充
  2. 解析URL的过程简述
  3. HTPP请求的基本结构和组成
  4. IP 地址、子网掩码以及DNS的基本了解,掌握概念和相关知识点。

讲讲历史

1991年8月6日,在瑞士日内瓦的核子研究中心(CERN)工作的英国物理学家蒂姆·伯纳斯·李(Tim Berners-Lee),正式提出了World Wide Web,也就是如今我们非常熟悉的www。

www是什么?万维网WWW是World Wide Web的简称,也称为Web、3W等。WWW是基于客户机/服务器方式的信息发现技术和超文本的综合技术

这里个人比较好奇我们天天都在说3w,3w,但是互联网是怎么出现的的书中并没有解释?

这里查了下网上资料根据个人理解解释一波:

实际上网络最开始苗头出现在美苏冷战的时期美国建立的APRA科研部门,被突然扯出来的科研部门一盘散沙不知道干嘛,对付苏联的科研工作也没什么进展,直到一个叫做罗伯特·泰勒的哥们出现,他的突破口是发现小型的通信网络不能兼容不同型号的计算机,我们都知道技术的顶峰就是定规则,毫无疑问他选择构建一套协议让所有的计算机都能遵守这一套规则干活。

于是他找来了几个牛逼的大佬开始捣鼓,中间巴拉巴拉做了很多事绕了很多弯,目的其实就是为了实现上面说的东西,最终在一次失败的“LOGIN”验证中虽然仅仅传输了“LO”两个字母就断开了,但是这次失败是历史性的进步,因为两个不同的设备实实在在的通信了,最终修复之后完成了这五个字母的正常传输。

随后捯饬出的ARPANET(阿帕网) 这个项目,也就是正式的互联网雏形。

课外知识到此结束,现在我们看看第一章主要看点:

  1. 如何解析网址?
  2. DNS 服务器如何查询域名对应的 IP 地址?
  3. DNS服务器如何接力?
  4. 浏览器如何将消息委托给操作系统发送给 Web 服务器?

核心是理解DNS的角色地位和作用,以及浏览器如何跟DNS交互完成网址(域名)解析为IP这一个操作的,本章最后的委托流程是整个第二章的重点内容,笔记顺其自然的放到了第二章笔记当中,为了方便理解把笔记归纳到第二部分。

如何解析网址

我们从URL开始,什么是URL,URL是Uniform Resource Locator的简称,专业解释叫做统一资源定位符,除开我们常见的http、https协议之外,浏览器还可以进行ftp文件上传,下载文件,发送电子邮件,浏览新文化等操作。

我们把这些行为看作是资源交互,虽然不同的资源交互会存在不同的URL组合,但是不管URL的组合形式如何变化,最终是开头决定一切,开头部分决定对待资源方式。

解析网址我们可以看下面的例子:

imgimg

碰到省略文件名的情况,通常下面几种:

  • http://xxxx/dir/表示 /dir/ 之后的内容被省略,这时候通常情况下会设置对应这个目录的真实访问路径进行补全
  • 对于web中最为经典的http://localhost:8080/访问路径,通常情况下Web服务器会访问到/index.html这个文件,如果没有就会返回404的页面。
  • 如果只有域名,比如www.baidu.com,那就会直接访问web服务器设置的根路径对应的资源和相关文件。
  • 含混不清的路径比如http://localhost:8080/wishlist,则会根据先判断是否为文件名,然后判断是否为目录的情况处理,或者看作一个请求映射到另一处资源,或者做一次重定向。

上面的内容不必深究,只需要明白浏览器的第一步工作就是对 URL 进行解析

Http请求

http请求简单来说可以简单概括为一句话:对什么做了什么样的操作,所谓对什么指的是URL,表示标识了的目标对象,做什么样的操作就是所谓的方法,方法主要是分为两个POSTGET方法,其他方法基本没啥用处,个人只在偶尔几个对接文档中遇到过PUTHEAD方法。

imgimg

GET方法:通常用于一些可见资源的访问,或者开放资源的访问,通常情况下不需要过多的限制就可以直接向具体的目录寻找需要的资源。

POST方法:比较常见的是使用表单或者 AJAX的方式访问,并且通常会指向一个WEB的应用程序,获取应用程序的数据需要传递服务器需要的一些有效参数,否则服务端会根据具体情况通知客户端无权访问。

AJAX即“Asynchronous JavaScript and XML”(非同步的JavaScript与XML技术),指的是一套综合了多项技术的浏览器端网页开发技术。Ajax的概念由杰西·詹姆士·贾瑞特所提出[1]。

Http请求消息

知道了 对什么做了什么样的操作,现在来看看Http 具体是怎么做这件事情的。

Http请求消息主要分为下面组织结构:

  • 第一行最开头的部分提取URL的内容,原封不动解析,末尾为HTTP版本号主要标记当前HTTP请求版本。

例如:GET /cgi/sample.cgi?Field1=ABCDEFG&SendButton=SEND HTTP/1.1

  • 第二行为消息头,这里列举一些简单的内容:
  • Data:请求响应生成日期。
  • Pragma:数据是否允许缓存。
  • Transfer-Encoding:消息主体编码格式(重要)。
  • Via:经过的代理和网关。
  • 消息头后面存在一行 完美没有内容的空行
  • 第四行为消息体,但是实验用的是GET方法所以通常内容为空。
imgimg

我们以访问谷歌为例,下面的内容访问谷歌搜索页面的一次请求参考,这里的内容直接通过谷歌浏览器的F12拷贝,可以看到基本包含了请求行,消息头和消息行(GET通常没有所以下面没有体现)三种。

代码语言:json复制
常规

1.  请求网址:https://www.google.com/
2.  请求方法:GET
3.  状态代码:200
4.  远程地址:127.0.0.1:7890
5.  引荐来源网址政策:origin

请求标头

1.  :authority:www.google.com
2.  :method:GET
3.  :path:/
4.  :scheme:https
5.  accept:text/html,application/xhtml xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
6.  accept-encoding:gzip, deflate, br
7.  accept-language:zh,zh-TW;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6
8.  cache-control:no-cache
9.  cookie:SID=KQi0QVpC_wxTynb6H6HjGmVq-9mYvCuIDOMx9EmEUJ8ii7dJzN_1F-ho69FdK6AN9ekOkA.; __Secure-1PSID=KQi0QVpC_wxTynb6H6HjGmVq-9mYvCuIDOMx9EmEUJ8ii7dJaTdIpqSfRfNb-BvF0haitA.; __Secure-3PSID=KQi0QVpC_wxTynb6H6HjGmVq-9mYvCuIDOMx9EmEUJ8ii7dJ6_WQQeEF09oAZ9MQfe21sA.; HSID=AOdmIhuBCutDeMwVS; APISID=ckyVXTB27QMaC2gQ/AVulr1cMnMbpD0e1x; SSID=AL0-0R0Ofsj3zaqrr; SAPISID=dqpTwJeh7bnii2Ki/AfsaDUfE8uMVR1aqv; __Secure-1PAPISID=dqpTwJeh7bnii2Ki/AfsaDUfE8uMVR1aqv; __Secure-3PAPISID=dqpTwJeh7bnii2Ki/AfsaDUfE8uMVR1aqv; SEARCH_SAMESITE=CgQIvJUB; 1P_JAR=2022-05-24-23; AEC=AakniGOKhznRpAD797X4u508i2XHJjEVYQQHANlqaJC2JSZ1F7mAe-vX_rg; NID=511=K-qt_LW-4ad1IYdJgfPLZjJw772wez2L3_FK9hwrrHAaksdhT8bTqz4icJEnJviOb92zcnyfS4h7P8HB_Is0f_FebYTe_5DR3qFEclHS1R9N1P7r9pv7Z4p12341S72RZRfzIlQ3-CVZUqQKBm1Xy1i9fKwejMGHTPMY2hk02sA--ey8nAEyt1_A7SVMe0RvrEkPnVm88fBnyyyFMMSCeSG1oqYKeC2x7iHJ0GwdbEpeGojpMQyQxAn1jAdxyXbC0oko0rCFjYn7eUREz2A9KA; SIDCC=AJi4QfGQeW0y_3pnzuBs7KI-WabF5XR_-dQchpcoNUN_bRVICBknb39qNQhP4IklnPn6kW4M3d8; __Secure-3PSIDCC=AJi4QfFOaoqiWv0mqmOskkIKVYy_-QNOATkPOyhNt9B8BBTMnRqnv-0zdgVgBNmIJRwlzBS4x6U
10.  pragma:no-cache
11.  sec-ch-dpr:2
12.  sec-ch-ua:" Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"
13.  sec-ch-ua-arch:"arm"
14.  sec-ch-ua-bitness:"64"
15.  sec-ch-ua-full-version:"101.0.4951.64"
16.  sec-ch-ua-full-version-list:" Not A;Brand";v="99.0.0.0", "Chromium";v="101.0.4951.64", "Google Chrome";v="101.0.4951.64"
17.  sec-ch-ua-mobile:?0
18.  sec-ch-ua-model:""
19.  sec-ch-ua-platform:"macOS"
20.  sec-ch-ua-platform-version:"12.3.1"
21.  sec-ch-ua-wow64:?0
22.  sec-ch-viewport-width:1440
23.  sec-fetch-dest:document
24.  sec-fetch-mode:navigate
25.  sec-fetch-site:same-origin
26.  sec-fetch-user:?1
27.  upgrade-insecure-requests:1
28.  user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36
29.  x-client-data:CLG1yQEIkrbJAQijtskBCMS2yQEIqZ3KAQjYjMsBCJShywEI2 /LAQjmhMwBCNupzAEI/qrMAQjDrMwBCKSvzAEYqKnKARirqcoB
30. 已解码:message ClientVariations { // Active client experiment variation IDs. repeated int32 variation_id = [3300017, 3300114, 3300131, 3300164, 3313321, 3327576, 3330196, 3340251, 3342950, 3347675, 3347838, 3348035, 3348388]; // Active client experiment variation IDs that trigger server-side behavior. repeated int32 trigger_variation_id = [3314856, 3314859]; }

响应内容

响应页面也是类似的需要回应请求行需要的内容信息,同时告知自己允许接受什么样的请求,如果目标IP找不到通常会变为404结果。

代码语言:json复制
响应标头

1.  accept-ch: Sec-CH-Viewport-Width  
2.  accept-ch: Sec-CH-Viewport-Height
3.  accept-ch: Sec-CH-DPR
4.  accept-ch: Sec-CH-UA-Platform
5.  accept-ch: Sec-CH-UA-Platform-Version
6.  accept-ch: Sec-CH-UA-Full-Version
7.  accept-ch: Sec-CH-UA-Arch
8.  accept-ch: Sec-CH-UA-Model
9.  accept-ch: Sec-CH-UA-Bitness
10.  accept-ch: Sec-CH-UA-Full-Version-List
11.  accept-ch: Sec-CH-UA-WoW64
12.  alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
13.  bfcache-opt-in: unload
14.  cache-control: private, max-age=0
15.  content-encoding: br
16.  content-length: 43734
17.  content-type: text/html; charset=UTF-8
18.  date: Tue, 24 May 2022 23:24:59 GMT
19.  expires: -1
20.  server: gws
21.  set-cookie: 1P_JAR=2022-05-24-23; expires=Thu, 23-Jun-2022 23:24:59 GMT; path=/; domain=.google.com; Secure; SameSite=none
22.  set-cookie: AEC=; expires=Mon, 01-Jan-1990 00:00:00 GMT; path=/; domain=www.google.com
23.  set-cookie: AEC=; expires=Mon, 01-Jan-1990 00:00:00 GMT; path=/; domain=.www.google.com
24.  set-cookie: AEC=; expires=Mon, 01-Jan-1990 00:00:00 GMT; path=/; domain=google.com
25.  set-cookie: AEC=; expires=Mon, 01-Jan-1990 00:00:00 GMT; path=/; domain=.google.com
26.  set-cookie: SIDCC=AJi4QfEXTiPm1BcAx1gfQzXOs-hmdcHylOVoSbbpy8cUIlP7hNwwfnfo_E8ZdTY1JZli8AqYYWk; expires=Wed, 24-May-2023 23:24:59 GMT; path=/; domain=.google.com; priority=high
27.  set-cookie: __Secure-3PSIDCC=AJi4QfFdxOIbJrwDKltt2sBRVFIcLOCyqQmgTSfYjXTYwqbhh0GPLcR9cxsgyaIh1j_GITbGeHc; expires=Wed, 24-May-2023 23:24:59 GMT; path=/; domain=.google.com; Secure; HttpOnly; priority=high; SameSite=none
28.  strict-transport-security: max-age=31536000
29.  x-frame-options: SAMEORIGIN
30.  x-xss-protection: 0  

响应内容相对比较简单,主要关注重点为第一行内容中的状态码和响应短语,请求执行结果是成功还是失败。上面的交互内容需要注意Http请求严格遵循一个请求对应一个响应内容。

注意:1 条请求消息中只能写 1 个 URI。如果需要获取多个文件,必须对每个文件单独发送 1 条请求。

“如何解析网址?”这个问题从头到尾的介绍到这里就完成的,接下来来看看下一个问题"DNS 服务器如何查询域名对应的 IP 地址?"。

IP 和 DNS

首先我们看看IP和DNS是啥,解析网址(域名)和发送请求和响应内容看似是浏览器完成的,实际上它并不具备这些功能, 浏览器收发网络请求实际上需要依托操作系统完成 ,而现代网络基本是TCP/IP 的天下,所以IP发挥关键作用,而DNS存储IP和域名映射的仓库。

  • IP:可以类比做我们现实的具体位置,比如XX路XX号,XX路(网络号)对应的的是分配给整个子网的号码,而XX号(IP地址)的号码则分配给子网中的计算机,获得到IP地址之后就相当于锁定了当前计算机所在的具体位置,自然也可以可以找到了。
  • DNS:直白来讲就是存储了域名和IP映射的记录的站点,浏览器要获取真实地址需要找DNS才能知道,因为域名放任用户自由定义将会出现同一个域名映射多个IP。

下面我们先观察XX路XX号的号也就是IP地址是如何被找到的。

发送网络的一方通过子网首先需要经过集线器,把内容转发到最近的路由器上,然后路由器会不断跨越找到离接受者更近的下一个路由器,最后再找到集线器然后在转发到接收者的路由器上,路由器在这里是方向盘的角色,而DNS寻址就像是导航。

imgimg

集线器和路由器是什么? A 路由器:一种对包进行转发的设备。 B 集线器:一种对包进行转发的设备, 分为中继式集线器和交换式集线器两种.

IP地址的组成

IP地址是一个32位的Bit数,通过8个bit为一组分为4组,每一组用十进制表示并且使用小圆点断开。

但是仅凭这32个bit是无法定位IP地址和网络号的,所以需要给IP地址附加信息。

通常IP地址的组合有下面的方法:

a)IP地址主体:11.22.33.44

b)IP和子网掩码:11.22.33.44/255.255.255.0

c)网络号的比特数作为子网掩码表示:11.22.33.44/24

d)子网地址:11.22.33.0/24,此时代表了整个子网

e)子网广播地址:11.22.33.255/24

首先整个IP分为32位固定长度,每四个为一组用圆点分隔,通过 0 - 255的十进制表示,比如0就是8个0,255就是8个1,但是仅仅凭借32个位数是没法辨别这32位那一部分是网络号,那一部分是主机号的,所以下面是IP的基本组成:

  • 11.22.33.44:表示基本的IP。
  • 11.22.33.44/255.255.255.0:前面部分是基本IP,后面的部分表示子网掩码,表示方式和IP地址一致,注意最后的8位全部为0表示整个子网。
  • 11.22.33.44/24: 这个24也是子网掩码,但是表示子网的方式是使用比特数。
  • 11.22.33.0/24: 子网掩码没有变,IP地址变了,最后的8位0也是表示整个子网。
  • 11.22.33.255/24: 子网掩码没有变,IP地址变了,最后的8位全部为1表示广播 整个子网。

什么是子网掩码?

初学者可能比较难以理解的概念,这里如果看不懂建议多找找资料挑一个看得懂的解释(关键是自己理解并且能自己复述)。

下面是从书中原图,个人看完感觉并不是特别直观也不知道干嘛,所以做了一个补充说明。

实际上下面图中网络号用了AND(位操作 &)计算出网络号码,计算之后确认出网络号是10.1.2,而后面省略的部分其实是8个0的掩码掩盖主机,这里的子网就是 10.1.2.0,对应的主机IP是10.1.2.3。

如果看不懂上面说的是啥,这里补充解释一下:

首先我们需要清楚子网掩码这东西是干嘛的,说白了就是划分网络号和主机号的,网络号可以看作一栋楼,主机是里面的小房间,但是房间编号可能是101,也可能是0101,更有可能是00101,具体得看掩盖的房间号从0000到1111有多少个,决定能分配给多少主机,而计算机0又很特殊,所以网络号的部分 子网掩码掩盖的位数部分(表现全为0)组成一个子网,只有在同一个子网的主机才能互相通信

所以子网掩码不能单独存在,它必须结合IP地址一起使用,子网掩码主要分为两个部分:全为1表示网络号,全为0表示的是主机号。

那么我们随便设置一个子网掩码比如255.255.255.111行不行?

答案是不行不行不行。因为子网掩码 必须是 连续的 1和0 组成,上面的掩码255.255.255.0 才是正确的用法,再举例比如255.255.255.244也是合格的子网掩码。

我们举例说明一下:

代码语言:SQL复制
1100 0000.1010 1000.0000 0001.1000 0001 -- 192.168.1.129
1111 1111.1111 1111.1111 1111.0000 0000 -- 255.255.255.0
———————————————————— 
1100 0000.1010 1000.0000 0001.0000 0000 -- 划分出最终子网网段:192.168.1.0
注:确认最终的网络号和主机网段使用了位操作 & (1 & 1 = 1,1 & 0 = 0)

从最终的结果来看192.168.1.0 的前面24位都为1是暴露的,而后面8位被子网掩码给遮掩住,所以他的另一种写法是192.168.1.0/24,表示24位是1代表网络号,剩余的8位用于表示主机号但是因为被掩盖了所以全部为0。

虽然被掩盖了,但是主机号位置是0是1不需要关心的,主机号如果落在192.168.1.0192.168.1.255表示同在一个网段内子网一视同仁,比如192.168.1.129表示其中的129位,包含在这个网段之内。

小结

  1. 子网掩码 必须是 连续的 1和0 组成,简单记忆为1的部分来分割网络号,为0的部分用于掩盖主机号,同一个子网内的主机可以互相通信。
  2. 子网掩码有两种写入方式一种是使用和I P 地址一样的32位完全表示方式,另一种是使用数字计算1比特数进行替换,比如24就是下面图中的24个1。
  3. IP 地址的主机号,全 0表示整个子网,全 1表示向子网上所有设备发送包。这里补充一下全为1的情况 - “广播”。

广播是什么意思?广播地址是专门用于同时向该网络中所有主机进行广播的一个地址,只要是在同一个网段的主机都可以收听到广播。(例如192.168.211.32/24的广播地址为:192.168.211.255

DNS

DNS: Domain Name System 域名服务系统,最常见的用法是将服务器名称和 IP 地址进行关联,当然只是它的主业,有一些副业也挺重要但是不是关键感兴趣了解即可。

IP是难以记忆的,而简短域名更容易被人记住。你可能会觉得域名长了也难记忆啊,虽然解析IP的速度要比解析域名来的快的很多,但是显然网民为了访问一个网站要记住一串数字显然是不可能的,同时域名实际上对于当时的互联网发展来说也是有意义的。

所以谁来告诉主机域名的真实IP是多少?这时候DNS就上场了,DNS的作用是说白了就是用来映射IP和域名的一个东西。

DNS是如何完成映射的?对于用户主机来说一定存在一个用于解析DNS的客户端,这个客户端通常被称为解析器,通过域名解析出IP地址的过程也被称为域名解析

调用解析器

那么如何调用解析器?解析器实际上就是一段程序代码,这一段程序代码包含在底层操作系统的Socket库当中,通过Socket库调用解析器,然后解析器会向 DNS 服务器发送查询消息, DNS 服 务器根据请求查询IP然后返回响应消息。

Socket 解析域名的过程非常简单,只需要一行代码就可以完成:gethostbyname("www.lab.glasscom.com");

库:指的是通用程序组件的集合,用于规范程序代码的规范组建。以解析器为例,Socket 库是用于调用网络功能的程序组件集合。

解析器内部又是如何工作的?

在应用程序调用解析器的时候,此时控制权会转移到解析器,当控制权转为解析器之后解析器会生成要发送给 DNS 服务器的查询消息,生成过程类似构建一条“请告诉XXX的IP地址”的消息,并且发给DNS服务器完成解析。

特别注意注意发送请求不是由解析器完成,而是需要再次委托给操作系统的协议栈完成,所以此时权限会再次转移到协议栈,协议栈最终通过网卡把消息发给DNS,然后DNS查到IP返回消息,至此一次DNS解析请求就完成了。

值得注意的是 解析器会将取出的 IP 地址写入应用程序指定的内存地址中,此外还需要注意请求DNS服务器本身IP也是需要配置的,只不过这个 IP 地址是作为 TCP/IP 的项目事先设置好的,不需要再去查询直接就可以获取。

最后在不同的操作系统中获取DNS服务器的地址方式会有差别。

根据上面的描述,总结DNS解析流程:

  1. WEB浏览器发送域名解析请求,通过Socket向解析器进行请求解析,此时应用程序将会挂起。
  2. 解析器负责“翻译”应用程序的DNS解析请求,但是把具体的请求操作委托给系统栈。
  3. 系统栈负责将请求通过网卡发送给DNS服务器,等待DNS反馈结果。
  4. DNS获取真实IP之后将结果通过链路反向回送到应用程序。

DNS工作

接下来我们看看dns要如何工作,dns需要查询用户消息包含下面几个部分:

  • 域名:用来替代IP方便记忆。
  • class:考虑到互联网之外的情况,当然外部网络现在只有标识为in的互联网。
  • type:表示记录类型用于区分dns的解析方式,不同类型结果不同。

需要注意的是所有a类型的记录在DNS上注册了,再比如所有邮件类型都是MX的类型,整个DNS工作其实就简单的根据类型和域名进行查表,找到匹配的就回传,否则就会找不到。

域名层次:所谓域名层次就是DNS不可能是一台服务器,而是需要多台服务器配合,各自管理自己范围的内容,而对于域名来说越靠右边的部分在域名的层次里面越高。

这样看来是不是有点意思,以日常生活举例并不是我们认为的www是最高,其实他是最低的等级,.com才是最高的。

DNS查找步骤

首先将负责管理下级域的 DNS 服务器的 IP 地址注册到它们的上级 DNS 服务器中,然后上级 DNS 服务器的 IP 地址再注册到更上一级的 DNS 服务器中,以此类推。

举个例子,需要解析等域名为www.baidu.com,DNS需要事先把整个www.baidu.com整个域名注册到baidu.com,再把baidu.com注册到com域名,再把com注册到根域,这样就可以通过上级找下级。

这里提到DNS有一个根域,根域名指的是就是一个句点 . ,和Linux的根路径意义表现形式上类似。

根据根域可以解释为什么任何奇怪等域名都可以被访问到,原因是所有的下级都会注册到上级中,最后都有一个共同的 ,如果所有下级要找到根域,自然需要注册根域这个句点。

DNS查找的过程是自下而上找最近的DNS然后自上而下找根域向下查找的的,也就是先找最近的dns找,没有找到就需要直接从根域进行查找,一路通过层级下探找到最终的ip,这也是为什么访问国外ip慢的原因,因为路由链路实在是很长,可能需要几十次dns搜索查找。

DNS缓存

如果每个主机每次请求总是要通过DNS获取域名对应的IP信息,是不可能每次都DNS让找一遍的,实际上解析到的真实IP会预先缓存起来下次访问重复的数据直接返回即可。

另外虽然前面介绍的是查找自上而下从根域向下查找,实际上DNS还可以利用缓存特性通过多个层级的共享域名加快访问速度跨级查找,比如www.baidu.comwww.baidu 可以共享缓存直接跳两个层级快速找到(当然这里其实找最近的一个DNS就能找到,这里仅仅是举例)。

但是缓存有个副作用,就是不存在的ip地址消息也会缓存,不过为了防止这种情况一般会有过期时间,过期之后依然需要再次走一遍DNS查找流程。

问题引导:问题

http://www.nikkeibp.co.jp/ 中的 http 代表什么意思?

表示的是HTTP 协议

下面两个网址有什么不同?

a. http://www.nikkeibp.co.jp/sample

b. http://www.nikkeibp.co.jp/sample/

区别点在于sample 可能被解析出和预期不符合的结果。

用来识别连接在互联网上的计算机和服务器的地址叫什么?

IP地址

根据 Web 服务器的域名来查询 IP 地址时所使用的服务器叫什么?

DNHS服务器

向 DNS 服务器发送请求消息的程序叫什么?

解析器。

《网络是怎么样连接的》读书笔记 - Tcp/IP连接(二)

代码语言:txt复制
**TCP和IP协议承载了整个互联网的生命线,这一章算是本书核心部分,掌握这两个协议也是学好网络编程的基础。**

本章重点

  1. Socket客户端连接细节,可以结合第六章服务端接收的细节对比学习
  2. IP和以太网的报文内容,以及MAC网络包如何封装,这里可以参考5层模型了解熟悉整个步骤
  3. UDP收发数据细节。

Socket连接

套接字链接在表面上看就是建立连接,交换数据,断开连接,虽然实际上细节肯定没有那么简单,但是大体上的思路基本不变。

协议栈建立连接

这里记住一个前提:向操作系统内部的协议栈发出委托时,需要按照指定的顺序来调用 Socket 库中的程序组件。

建立Socket的协议大部分情况都是Tcp/ip协议,Socket收发数据类似在两个主机之间建立一个无形的管道,Socket建立的关键是要按照指定顺序调用Socket程序组件,大致的构建顺序如下:

  1. 创建Socket(Socket类似管道两边的出入口)
  2. 绑定客户端的套接字到服务端(类似接管道)
  3. 交换数据。
  4. 断开Socket连接,解除绑定。
代码语言:txt复制
转化为具体的流程图如下:

创建Socket

过程大致为应用程序会把控制流程会转移到 socket 内部并执行创建套接字的操作,完成之后控制流程又会被移交回应用程序。

创建完套接字之后,协议栈需要返回标识符号也就是描述符用于标识是哪一个套接字在进行传数据,因为我们可能打开很多套接字连接访问不同的网站,具体的效果是我们浏览器会打开很多个页面,这时候每一个页面都可能需要创建套接字,此时就需要识别和区分这些套接字依赖描述符。

绑定客户端的套接字到服务端

代码语言:txt复制
连接操作核心是调用Socket的connect连接方法,此方法需要指定**描述符、 服务器 IP 地址和端口号**这 3 个参数。
代码语言:txt复制
connect看上去挺复杂,其实本质上就是完成连接动作而已,连接成功会把IP地址和端口号记录到套接字上面。

描述符在创建Socket的时候已经拿到了,IP地址则是在DNS解析的步骤完成,拿到IP之后会放入到应用程序的某个位置替换保存,而端口号则是需要应用程序事先提供。

端口可以简单看作应用程序的入口,DNS解析的IP只能知道主机在哪但是本身发往哪个应用程序是不清楚的,我们可以想象DNS解析类似地图上告诉我们高速的收费站坐标,但是他并不知道对应数据送往那个闸口)。

这里可以理解为端口就是收费站过站口,计算机会要求程序对待应用程序预设明确的端口参与网络交互。

传递消息

接下来的操作是调用read和write函数完成消息传递动作,这一步就是底层的流读写操作。

断开连接

代码语言:txt复制
这一步需要简单理解为需要一方主动发起断开申请浏览器调用read收发数据同时会收到关闭请求,此时客户端确认请求之后将会停止请求并且开始释放Socket连接。

为什么不能用描述符标识应用程序的入口?

描述符是和委托创建套接字的 应用程序进行交互时使用的,并不是用来告诉网络连接的另一方。

客户端也无法知道服务器上的描述符,客户端也无法通过服务器端的描述符去确定位于服务器上的某 一个套接字。〉

Socket连接中大致介绍了协议栈是如何通过网卡完成和目标服务器的连接、断开、收发数据的过程下面按照顺序讲述各个步骤的细节。

下面我们根据上面所讲的各个步骤按顺序进行详细介绍。

创建套接字

首先来看一下创建套接字的情况,下面是协议栈的内容。

代码语言:txt复制
委托分发被拆分为好几个部分,最上面可以看作浏览器,协议栈中主要有两张协议 TCP和UDP, TCP主要是用于和服务器交互收发数据的,UDP则用于较短的控制数据。
代码语言:txt复制
IP协议主要控制网络收发操作,主要工作是把一个个拆分的网络包发给通信的目标对象,IP协议包括 ICMP和 ARP协议,前者告知传输过程的错误和控制信息,后者传递以太网MAC地址。

MAC 地址:符合 IEEE 规格的局域网设备都使用同一格式的地址,这种地址被称为 MAC 地址

驱动部分是为了让操作系统能正常使用硬件进行网络收发的一个“适配器”,而所有的电信号最终要通过网卡完成。

套接字和协议栈

协议栈实际上是根据套接字传递的信息来决定做什么操作的,比如发数据要看IP和端口号。

以Windows的套接字为例,直接在CMD中使用 netstat操作即可:

代码语言:sql复制
C:UsersXander>netstat -ano
  协议     本地地址             外部地址                    状态           PID
  TCP    0.0.0.0:49666          0.0.0.0:0              LISTENING       604
  TCP    0.0.0.0:49667          0.0.0.0:0              LISTENING       1892
  TCP    0.0.0.0:49668          0.0.0.0:0              LISTENING       4508
  TCP    0.0.0.0:57621          0.0.0.0:0              LISTENING       22748
  TCP    127.0.0.1:1001         0.0.0.0:0              LISTENING       4
  TCP    127.0.0.1:1043         127.0.0.1:1061         ESTABLISHED     8452
  TCP    127.0.0.1:1043         127.0.0.1:1063         ESTABLISHED     8452
  UDP    192.168.159.1:1900     *:*                                    3060
  UDP    192.168.159.1:5353     *:*                                    5248
  UDP    192.168.159.1:58085    *:*                                    3060

netstat 命令 的 ano 三个参数主要用于扩展IP地址端口以及PID的显示,以及一些隐式的可能存在的通信也会被记录。

LISTENING:表示等待对方连接 ESTABLISHED :表示完成连接并且进行数据通信操作

套接字和协议栈和应用程序的交互流程如下:

  1. 协议栈在操作套接字之前,需要事先开辟一块空间来存放用于操作套接字的必要信息。
  2. 协议栈需要向应用程序返回描述符表示当前连接的是哪一个“管道”。
  3. 之后应用程序需要和协议栈交互就必须要携带描述符,不过这样也节省了协议栈了解应用程序要和哪一个套接字交互。

连接服务器

连接的目的是为了让两台不再同一个地方的主机能够相互认识对方,这时候不可避免的需要互相提供自己的信息,这样才能正确的建立连接然后使用套接字传输数据。

连接的含义

人和人之间的沟通有时候可以不使用一个语言,只要双方都听懂就行,但是对于计算机是行不通的。

所以连接操作的控制信息要根据通信规则确定,协议栈在通信之前需要依靠一块空间来存放必要数据,这块内存空间称为缓冲区。

连接需要双方各自告知自己的信息,所以连接最开始的时候是没有任何数据交互的,由于是TCP是全双工的协议客户端和服务器都需要建立套接字,不过双方不知道和谁连接,所以需要在客户端和服务端各自开辟一块空间来存放对方的IP和端口等必要的传输信息。

为了让双方既可以正常通信,又可以根据自己的系统设计协议栈和套接字的控制信息处理方式,网络通信设计采用了 控制信息的的方式让不同计算机和系统能相互认识。

所谓的控制信息可以认为是一种 通用语言,只要是符合这个控制信息规范的头部信息就可以被其他的计算机认识。

控制信息分为两类:

  1. 客户端和服务器的交换的控制信息,主要用于整个通信过程,这些内容在TCP协议进行规定。生活的例子理解是我们和别人通话之前,两边都得知道对方的电话号码和基本身份。
  2. 保存在套接字中用来控制协议栈操作的信息,这些信息主要用来传输数据,通常需要包括通控制信息和数据块,套接字需要通过控制信息了解到发来的是什么类型的数据,然后协议栈才能配合处理数据。

由于在一开始传输的时候是没有具体数据的,通常是一个空的报文头,所以这个控制信息也被叫做 协议头部, 比如下面提到的TCP头部,IP头部。

第一类:TCP 头部格式

第二类:套接字中的信息

连接的实际操作

连接的实际操作主要是调用CONNECT函数,协议首先会传递给TCP模块,通过TCP模块交换获取控制信息的头部,以此了解具体要连接的套接字信息,然后把头部的SYN比特设置为1,表示可以连接。

TCP 模块处创建表示连接控制信息的头部,接着便把信息传递给IP模块进行委托发送。

三次握手

交换头部信息之后,接着便是常见的TCP三次握手的过程:

  • 第一步:客户端主动打开TCB端口,服务器被动打开TCB端口。发起方携带一个SYN标志,并且携带一个ISN序号Seq=x,但是需要注意的是第一步的过程这个ISN序号是隐藏传递的(因为没有传递数据),因为如果请求不存在数据的交换则不会被显示。客户端发送SYN命令之后进入设置SYN=1,并且设置SYN-SENT(同步-已发送状态)。
  • 第二步:服务器收到客户端TCP报文之后,也将SYN=1,并且回送一个新的ISN序号ack=x 1,并且将ACK=1表示自己收到了,然后在返回参数回送自己新的序列号表示自己的确认请求Seq=y,将状态设置为SYN-RCVD(同步收到)状态,(表示希望收到的序号为xxxx1522),最后也是指定MSS。
  • 第三步:客户端收到服务器的确认报文之后,还需要向服务端返回确认报文,确认报文的ACK=1,并且回传服务器传递的ISN序号 1(ack = y 1),以及自己的ISN序号 1(Seq = x 1),此时TCP连接进入已连接状态,ACK是可以携带数据的,但是如果不携带数据则不消耗序列号。
  • 最后一步:当服务器收到客户端的确认,也进入已连接状态。

经过三次握手连接建立,直到断开连接之前都可以传递数据。

收发数据

收发数据有两个重点:

  • 第一点是收发数据并不关心数据的格式,而是根据头部信息来辨别是什么类型的数据,对于协议栈来说接收的的内容都是二进制的数据。
  • 第二点是利用缓冲区减少频繁的数据传输提高传输效率。

缓冲区的大小如何控制?

  • 每个数据包的数据长度,协议栈会根据一个叫作 MTU的参数来进行判断,但是MTU指的是总长度,除开头部信息之后获得真实的数据长度MSS
  • 时间,这个时间指的是固定的时间内容不管缓冲区有有没有达到MSS长度必须发送数据的时间,目的是防止等待时间过长造成请求延迟。

名词解释:

MTU:一个网络包的最大长度,以太网中一般为 1500 字节。 MSS:除去头部之后,一个网络包所能容纳的 TCP 数据的最大长度。

但这两个因素实际上并不能完全决定收发数据的效率平衡,TCP协议没有规定协议栈如何平衡,具体需要看操作系统如何决定。

实际上协议栈收发数据是有所保留的,并不是强制按照协议的规定处理,而是给了应用程序一些可控选项,比如浏览器这种要求实时性的应用程序通常不使用缓冲区

Http请求拆分

通常情况http的请求响应内容可以通过一个网络包完成,但是针对POST请求等大表单的数据提交则通常会触发TCP拆包操作。

拆包是根据MSS的参数确定的,发送缓冲区会根据这个参数把一个超过一次请求长度的数据拆分为多个包,但是因为实际上同属一份数据,拆分之后所有的数据包都需要添加相同的头部。

注意:TCP是面向字节流的协议,就是没有界限的一串数据,本没有“包”的概念,“粘包”和“拆包”一说是为了有助于形象地理解这两种现象。

TCP粘包

TCP除了拆包动作之外还包含粘包的操作,所谓粘包是指TCP协议中发送方发送的若干包数据到接收方接收时粘成一个包,从接收缓冲区角度来看后一个数据的头紧接着前一包数据的尾部。

解决粘包、拆包问题策略?

代码语言:txt复制
粘包和拆包需要解决容易造成半包读写的根本问题,解决办法也有很多种,主要的策略基本很多网上资料都有讲到,这里直接搬运结论了:
  • 请求消息定长,如果缓冲区不满,则通过补0的方式达到长度,防止粘包和拆包。
  • 在包尾增加回车换行符进行分割,例如FTP协议;
  • 将消息分为头部和消息体,头部中保存整个消息的长度,只有读取到足够长度的消息之后才算是读到了一个完整的消息;
  • 通过自定义协议进行粘包和拆包的处理。(几乎不用)

ACK号确认网络包收发

ACK号码除了在三次握手的过程中确认对方是否有收到请求之外,还能作为判断接收的数据包是否完整的依据,在进行数据传输的时候,接收方会将到目前为止接收到的数据长度加起来,计算出一共已经收到了多少个字节,然后将这个数值写入 TCP头部的 ACK 号中发送给发送方,以表示自己到底受到了多少数据,如果中间存在缺少数据则服务端重新传输即可。

当然仅靠ACK号不能完全作为参考依据,并且只使用ACK号是只考虑 单向传输的情况,但是TCP是全双工协议,无法确定数据接收方来自哪一方。

解决这个问题也很简单,实际在进行双向数据传输的时候双方各自会额外计算一个序号,序号其实就是一组随机数,在接收方收到数据之后每次都需要把序号 1回传给发送方表示自己接收到哪一个序号之前的所有数据。

通过ACK 序号的方式确保数据正确传输,这样可以使得其他网络通信组件不需要额外的失败补偿机制,如果发现丢包或者数据不完整的情况,直接根据序号进行重传重发的操作即可。

影响数据传输的因素

主要影响因素是返回ACK号的等待时间。

如果ACK号迟迟没有响应给对方服务器,势必会影响整个网络传输的效率,如果下一个数据已经准备好上一个返回包却没有发回去,很容易造成网络的堵塞,对方迟迟拿不到正确结果。

网络环境的复杂多变,这个等待时间不可能是固定的,所以TCP使用了动态时间的方法进行调整,具体的调整方法就是使用滑动窗口

滑动窗口

滑动窗口:指的是在不等待ACK返回结果的情况下直接双方互相不间断的发送数据。

双方需要通过各自的缓冲区顺序返回ACK信息,但是如果无限制的发送数据会导致数据无法处理出现丢包,所以滑动窗口的关键是接收方需要告诉发送方自己最多能接收多少数据

滑动窗口的细节通过一张图更好理解:

关于接收方的接收量,最大能承受处理多少数据是通过缓冲区大小确定的。另外需要注意下面的图只有单向的部分,实际上对于双向来说都是类似的处理。

影响数据传输的次要因素:返回 ACK号和更新窗口的时机

关于这一点直接记住一个结论,接收方在发送 ACK 号和窗口更新时,并不会马上把包发送出去,而是会等待一段时间,等到其他的通知合并到一起处理,因为ACK号体现的是已经收到的包的数据量,使用这样延迟发送的方式也可以防止过多的更新数据包出现。

最终协议栈收发数据的细节如下:

  1. 协议栈会根据收到的数据块和TCP或者IP头部解析内容,如果确认收到数据则返回ACK 序号。
  2. 协议栈会把数据块放到缓冲区进行存储,利用滑动窗口的特性按照顺序处理数据交给应用程序处理。
  3. 协议栈会将接收到的数据复制到应用程序指定的内存地址中,然后将控制流程交回应用程序

断开连接

断开连接的部分包含断开连接和删除套接字的操作,断开连接也就是经典的四次挥手的操作,而删除套接字则需要注意在协议栈中并没有规定关闭的时间,但是通常情况下过几分钟之后会删除套接字。

四次挥手端口tcp连接

  • 第一步(客户端):TCP发送释放连接的报文,停止发送数据,释放报文首部,把FIN=1,同时发送序列号,根据上一次传送的序列号 1传送Seq = t 1(由于下图是在连接之后立马进行四次挥手,所以序列号没有变),此时客户端进行终止等待1的状态。注意FIN不携带数据也需要消耗序列号。
  • 第二步(服务端):服务器回送确认报文,发出确认报文,ACK=1,并且把回传序列号 1回传(ack = t 1),然后再带上自己的序列号Seq = y,此时服务端进入CLOSE-WAIT状态(关闭等待状态),TCP服务器此时需要停止上层应用客户端向服务端请求释放,处于 半关闭 阶段,此时服务端依然可以向客户端发数据并且客户端需要接收并处理,关闭等待状态意味着整个状态还需要持续一段时间。
  • 第三步(客户端):客户端接收到服务端确认请求,此时客户端进入到FIN-WAIT-2终止等待2的阶段,等待服务器的释放报文。(还有一部分服务器没有发送完的数据需要处理)
  • 第四步(服务端):服务器把最后的数据处理完毕,向客户端发送释放报文,FIN=1,ack=t 1,由于需要把剩下的数据发送完成,假设处理完成之后需要带上自己的序列号Seq=w,服务器进入最后确认状态,等待客户端确认。
  • 第五步(客户端):客户端收到报文之后,发出确认 ACK=1,ack=w 1,自己的序列号为Seq = t 1,此时客户端进入到了TIME-WAIT(时间等待状态),此时客户端还是没有释放,必须经过**2 * MSL(最长报文寿命)**之后,客户端撤掉TCB之后才进入CLOSED状态。
  • 第六步(服务端):服务器收到客户端的请求立马进入CLOSE状态,同时撤销TCB,结束此次TCP的连接。(服务端结束TCP连接要比客户端早一些)

套接字和协议栈和对方服务器的交互流程细节还是比较多的,这里可以发现实际上三次握手和四次挥手实际上只是网络连接当中很小的一部分,最后是从连接服务到数据收发到断开连接的一张简单总结图,建议当作一个大概的流程参考:

IP和以太网的收发操作

上面的部分比较贴近TCP协议的相关操作,TCP完成连接收发的同时其实都需要IP模块的配合,在了解这两个模块如何配合工作之前需要了解完整的网络包是如何组成的。

包的组成

对于任何一个网络包,都有最外层的抽象概念,那就是头部数据 两个部分

上面的部分有一个这样的图,里面套接字中的TCP数据,这里需要注意在TCP控制信息的前面就是以太网和IP的控制信息,对于只传输控制信息的网络包虽然没有数据的部分,但是可以把协议的头部信息作为数据部分。

通过下面的图也可以发现,所有的网络包必须要委托以太网和IP控制信息才能完成传输。

把存放数据的网络包进行拆分,可以看到下面的TCP/IP 包结构:

我们可以简单把头部和数据看做是平时的快递,头部是面单,指示从哪里到哪里,然后这个“快递”会通过网络转发设备的查表操作判断传输到那个方向。

转发设备是什么?这里建议看看第一章的关于认识网络传输的基本概念,这里简单提一下:

  • 路由器根据目标地址判断下一个路由器的位置
  • 集线器在子网中将网络包传输到下一个路由

但是实际上集线器和路由器各自有不同分工,集线器负责管理以太网规则传输包设备,路由器管理IP转发规则,所以上面两个步骤也可以做下面的理解:

  • IP协议根据层级规则判断下一个IP转发设备。
  • 子网的以太网协议转发给下一个转发设备。

实际上头部部分应该分为 MAC 头部 和 IP头部。为什么要把头部拆分为两个协议?实际上是为了让协议之间可以实现替换,比如MAC可以替换为局域网、ADSL、FTTH。同时因为互联网这样庞大的网络架构,需要更加细化的分工。

小结

实际上网络包的封装应该范围三个部分:

第一部分是TCP模块组织头部信息和数据包(当然也可能没有数据只有控制信息)。

第二部分是把整个TCP模块塞到IP模块的后面,然后经过网卡发送出去。

第三部分是在IP模块前面加上Mac信息。

关键:无论要收发的包是控制包还是数据包,IP 对各种类型的包的收发操作都是相同的。

名词解释 ADSL:可以理解为以前宽带使用拨号连接互联网上网的方式。

非对称数字用户线路(英语:Asymmetric Digital Subscriber Line)又称非对称数字用户环路Asymmetric Digital Subscriber Loop),简称ADSL。ADSL是一个依靠铜质电话线的数据传输技术比传统的调制器更快。

FTTH:其实就是现在的光纤通信。

光纤到户(英语:Fiber To The Home,缩写:FTTH)是一种光纤通信的传输方法。是直接把光纤接到用户的家中(用户所需的地方)。

这种光纤通信方式及策略与FTTN、FTTC、HFC(Hybrid Fiber Coaxial)等也不同,它们都是需要依赖传统的金属电线,包括双绞线及同轴电缆等,作“最后一哩”的信息传输。

IP 协议头部

IP类似快递上的单号,所以实际上IP模块是无法决定自己选择正确的地址了,哪怕应用程序通过TCP告诉IP发的地址式是一个错误地址,IP也无法自行修正只能照做。

从这样的特点可以看出IP头部又有点类似快递员,和网上买东西商家发错地址或者我们填错地址一样,不能把责任赖在快递员上。

IP协议头部的组成类似下面的结构,注意IP地址的长度固定需要32Bit的空间占用。

这里需要注意“发送方的IP”地址不是指计算机的IP,而是指网卡对应的IP,因为IP不是分配和计算机而是网卡的,当一个计算机有多个网卡就会存在多个IP。

那么应该如何判断包发送给哪一个网卡?这里涉及到IP协议规则,无论是路由器的转发还是协议栈的处理都需要按照IP协议转给下一个用户。

查询分配给哪一个网卡在不同操作系统中的查询方式不同,查询发送端需要查询是哪个网卡把包发给了路由器,这个动作只需要简单的根据路由器IP地址和网卡的IP进行比对。

在windows中可以通过命令route print查看路由信息。

获取IP和网卡之后,还需要知道包所属的协议,委托内容是固定的,比如TCP模块就是06,UDP就是17,大部分请求都是HTTP,使用TCP的方式传输。

以太网Mac头部

TCP/IP模块只能在传输层上互相了解,但是往下的链路层以太网用同样的规则是行不通的,所以头部加上TCP/IP的头部之后,还需要在头部加上Mac头部,Mac头部包含了发送方和接收方的Mac信息,这里可以简单理解为Mac和IP的作用类似,不过Mac头部是48Bit,而IP头部是32Bit。

需要注意以太类型就是Mac包装的后面的真实数据的类型, 如果是IP就是IP协议。另外需要注意在发送Mac包给接收方之前,由于不知道对方的Mac地址,所以还需要一步查询操作。

注意IP 模块根据路由表 Gateway 栏的内容判断应该把包发送给谁。

下面是Mac头部的组成:

查询Mac地址

查询对方的Mac地址需要用到ARP( Address Resolution Protocol,地址解析协议),ARP通过广播的方法查找到目标地址,所谓广播就是字面意思把消息发给所有的其他互联网用户,等待对方应答。

为了防止每次查询都要带ARP的数据,所以有一块ARP的缓存专门缓存这个地址,但是需要注意这个缓存和IP模块的IP地址一样,过一段时间会被ARP缓存淘汰掉,但是如果IP刚刚变化可能会导致ARP缓存未及时更新导致网络异常。

实际整个工作都是由IP模块完成的,虽然Mac地址是以太网数据传输的必要内容,但是实际上让IP模块负责这些工作是有利的。

为什么需要以太网?

# 有了 IP 地址,为什么还要用 MAC 地址?

以太网基本知识

首先来看看以太网的基本发展,虽然设计结构越来越精细,但是本质上干的活却没有发生变化。

以太网早期原型本质上可以看作是一根网线以及一个用于收发的设备,网络信号发送之后通过广播最终到达所有设备,在开头的收发信息让其他人可以知道信息最终要发给谁,在Mac头部就包含了“收货地址”,而具体发送了什么类型的可以通过上面的“以太类型”进行判断。

以太网在后续的发展中将主干网线替 换成了一个中继式集线器,收发器变成双绞线,虽然形式变了,但是本质的工作没有变。

以太网到了现代最终由交换式集线器完成所有的操作,并且网络请求只有请求方和接收方可以互通,集成度增加以及网络传输安全性能增加。

但是以太网无论怎么发展性质始终没有任何变动:

MAC 地址代表的目的地,用发送方 MAC 地址识别发送方,用以太类型识别包的内容。

IP模块转光(或电)信号

网络信号发送依赖网卡,但是网卡并不是插上电就可以使用的,还需要依赖初始化以及驱动程序才能完成操作,驱动程序和初始化操作在其他很多电脑硬件中比较常见,但是以太网有比较独特的驱动操作,那就是控制以太网收发操作的MAC当中收发MAC地址。

另外网卡还有一个特性是网卡的 ROM 中保存着全世界唯一的 MAC 地址,这是在生产网卡的时候就已经决定。

所以可以看到最终完成IP数据转化的关键是驱动程序,网卡中保存的 MAC 地址会依赖网卡驱动程序读取并分配给 MAC模块。

网络包的控制信息

MAC模块工作在网卡调用MAC包发送请求命令之后,MAC模块的工作是划分网络包的“边界”。

为了划分边界,MAC模块会加上三个控制信息:

  1. 报头:是一串像 10101010…这样 1 和 0 交替出现的比特序列,长度为** 56 比特**,它的作用是确定包的读取时机
  2. 起始帧分界符(SFD):确定帧的起始位置,主要是辅助电信号切分报文头部和真实的网络包边界,并且判断出每个比特的界限。
  3. FCS:检查包传输过程中因噪声导致的波形紊乱、数据错误,它是一串 32 比特的序列,是通过一个公式对包中从头到尾 的所有内容进行计算而得出来的

响应内容传输从IP给TCP

当服务器接收到网络包之后,首先协议栈会判断以太网头部的以太类型,发现是0800为TCP/IP协议,接下来是IP模块工作,首先是检查IP头部是否正确,IP地址是否正确。

如果接收方是window客户端,因为不会对包进行转发,如果发现包不是发给自己的,会调用ICMP消息回传给请求发送方,IMCP的消息格式如下:

另外接收到的网络请求可能会因为数据包过大出现IP分片,分片的包会在 IP 头部的标志字段中进行标记,IP模块会把分片过的包暂存内部内存空间,等相同ID的包全部接收到缓冲区之后再拼接。

怎么保证拼接的顺序正确呢?可以查看前文IP 头部还有一个分片偏移量(fragment offset)字段,它 表示当前分片在整个包中所处的位置。

IP模块完成数据分片重组之后,数据包交给TCP模块操作,TCP还会再次检查一遍请求方和接收方的IP信息,以及获取端口号找到对应的套接字,找到套接字之后根据应用程序的类型进行不同的操作,这个过程可能是建立连接,也可能是完成应用程序数据的读写操作。

这里可能会觉得IP检查不是IP模块的操作么,TCP去看IP模块的信息是不是“越权”了?实际上这是一种性能开销都考虑而违反“迪米特法则(Law of Demeter)”的一种特例。因为TCP模块需要频繁使用IP模块的信息,如果老是需要数据之间的交互传输非常影响性能。

UDP协议收发操作

TCP/IP为了保证数据准确收发需要使用一系列复杂的模块和过程配合保证数据的完整传输,但是有时候有些应用程序为了保证高效会舍弃使用TCP这种复杂的机制。

UDP协议的要点是尽可能将所有的数据通过一个包解决,UDP 没有 TCP 的接收确认、窗口等机制,因此在收发数据之前也不 需要交换控制信息。UDP的实现非常简单只需要应用程序加入头部,直接交给IP模块完成即可,接收方也只需要检查IP头部的发送方和接收方的IP地址信息,然后再从UDP找到端口号,最后再找到套接字信息把数据给应用程序。

因为UDP不保证传输的稳定性所以无论包是否接收到都无关紧要,只要对方没有回应直接把包进行重发即可。这种不需要保证传输稳定性的场景还是有不少的,比如聊天数据、音频和视频信息,即使丢失一点点也没有关系,最多是卡顿一下而已。

关键:UDP 可发送的数据最大长度为 IP 包的最大长度减去 IP 头部和 UDP 头部 的长度。一般来说 IP 头部为 20 字节UDP 头部为 8 字节,因此 UDP 的最大数据长度为 65507 字节。

下面是UDP的头部信息:

小结

在第二章我们了解Socket链接的步骤和大致细节,另外介绍了整个互联网比较重要的两个协议TCP协议和IP协议,在两个协议中需要重点掌握头部设计,IP模块完成TCP模块的数据,TCP数据封装应用程序数据,之后还需要配合Mac以太网模块完成网络包的最后封装,等一切准备工作完成之后,由网卡以及驱动程序把整个包发送出去,所以其实可以看到决定你能不能上网等实际上是网卡和驱动(这不是废话),但是这些内容属于不同层级的内容,需要一一消化。

介绍了TCP之后,在在第二章最后部分简单提到了UDP协议,UDP是一种简单暴力的协议,设计的目的是让所有的数据尽可能通过一个包完成,所以他不需要链接也不需要保证数据安全传输,数据丢了直接传输即可,UDP的应用也是十分广泛的,比如游戏,视频,音乐等等数据的传输,很多时候丢一点根本无关紧要,因为即使找回来这些数据也没有意义。

TCP/IP连接也只是互联网数据传输的一小部分,但是却是最为核心的部分,虽然往下还有以太网和网卡以及网络通信如何上网等细节,但是只有深刻了解TCP/IP协议才能了解整个互联网是如何交互和数据传输的。

《网络是怎么样连接的》读书笔记 - 集线器、路由器和路由器(三)

本章重点

  1. 信号如何在网线和集线器中传输?如何抑制信号传输中的失真情况?
  2. 交换机的作用和工作方式是什么?
  3. 路由器包转发的细节,以及和交换机的区别。
  4. 路由器额外功能了解,不仅仅是接入互联网的媒介,还包含许多其他功能。
  5. 了解集线器、路由器、交换机在OSI模型(TCP/IP模型)的位置。

集线器和网线信号传输

如果了解[《网络是怎么样连接的》读书笔记 - ADSL]和[《网络是怎么样连接的》读书笔记 - FTTH]两个部分的内容,应该清楚网络包在传输的过程中最终转化为电信号或者光信号传输,我们通常所说的TCP协议、IP协议、以太网等等实际上都已经被“屏蔽”的。

最终包的传输只是一个转发设备到另一个转发设备信号传输,所有的网络包都相当于一个独立的快递一般进行传输。

这个传输过程涉及到本章的三个最重要的内容,也就是集线器,交换机,路由器,整个传输的过程和下面的内容类似:

防止信号衰减

所谓的以太网信号实际上可以看作是正负变化的电压,网卡的PHY模块负责完成正负电子信号电路输出。

信号传输的根本性的问题是网线越长,信号衰减和损耗越严重。由于以太网是使用方波信号传输,高频信号容易丢失,这样容易导致信号的失真,另外线路噪声条件无论好坏都有可能导致信号失真,所以问题很显然是在传输材料上。

互联网最早使用的是双绞线,所谓双绞线是最早期的ADSL的接入互联网而使用的电话线和网线混合的模式诞生的一种特殊设计模式。

而最早的以太网使用专用同轴网线,后来变成由美国室内电 话线改良的版本,原因是它可以兼容电话线的布线工具和材料, 比较方便。

想要双绞线如何避免信号失真和噪声问题,我们需要了解噪声是怎么来的,这里需要介绍一点物理知识:

信号噪声来自于网线周围的电磁波,影响网线信号传输的电磁波主要有两种,第一种是液晶显示设备泄漏的电磁波,第二种是相邻的网线产生的电磁串扰,信号传输依靠的是电流,电流在经过网线周围周围就会产生电磁波,网线之间的电磁波干扰被称为串扰

要解决上面两种电磁波的问题,通常有下面的方式:

  1. 第一种通过双绞的方式让电流通过不同的方式以螺旋的方式传输,其中两根信号线中产生的噪声电流方向就会相反,这时候信号依然可以正常传输,但是噪声得到了控制。
  2. 第二种电磁串扰问题可以通过绕线的方式来解决,由于绞线之间本身就有十分规律的间隙,正反信号之间的距离通过缠绕的方式进行抵消,所以哪怕相邻只要互相缠绕方式正确就可以让噪声进行抵消。

所以网线螺旋缠绕方式本身是有讲究的,既可以解决电流本身掠过其他电磁波设备产生的噪声,又可以防止不同网线交叉的电流产生的电磁波噪声。

集线器工作

信号传递到整个网络之后将会广播到整个网络,在第一章“以太网MAC头部”当中介绍了MAC地址中包含了接收方的“收货地址”,集线器负责以太网架构中对于信号进行广播的角色。实际上可以想象是接收一端网卡传递的电信号,然后通过网线传递给另一端。

我们可以观察集线器的设计,PHY模块的功能基本是相同的,注意这里的接线方法是交叉连线的,使用直接连接的方式是无法接收信号的。

如果集线器不想和某个网卡通信则需要一个中间媒介完成切换的动作。

RJ45接口:通常用于数据传输,最常见的应用为网卡接口。 RJ45是各种不同接头的一种类型;RJ45头根据线的排序不同的法有两种,一种是橙白、橙、绿白、蓝、蓝白、绿、棕白、棕;另一种是绿白、绿、橙白、蓝、蓝白、橙、棕白、棕;因此使用RJ45接头的线也有两种即:直通线、交叉线

为了让不同的接口实现“接入”和“关闭”的操作,需要依赖MDI/MDI-X 切换开关,如果存在这个开关的则可以切换MDI/MDI-X 模式,集线器直接的连接可以都改为MDI 模式(也就是直连模式)。

但是如果需要和其他计算机的网卡交互,需要切换为MDI-X 模式进行交互,另外注意不是所有的集线器都有切换开关,所以如果某个集线器只有MDI-X 接口,也可以通过默认的MDI- X接口完成交叉交互。

这里可能有点难以理解,所以换一种解释:我们知道电流是从正极流向负极,所以在集线器和两个计算机的网卡交互的时候是需要进行“发送端”和“接收端”的正反交叉连接。

而集线器的设计由于是“平行设备”,可能存在只支持正反信号交互或者直接连接的方式完成交互,所以需要模式的切换开关进行兼容,但是如果集线器只有正反信号的交互接口,则直接通过交叉交互连接的方式完成信号交流。

现在我们再看看另一端接收内容拼接成一个完整的结构图,和前文所说的一样在网卡的这一端。

为什么有直连和交叉线?

下面的部分是书中没有介绍的内容,个人存在疑问为什么集线器要弄出MDI/MDI-X 直连和交叉的模式,虽然知道了他的作用,但是不清楚历史由来。

为了详细解释,首先说一下什么是直连线,什么是交叉线。

  • 直连线:网线两端都是按T568A或者T568B排序。
  • 交叉线:一端是按T568A排序,一端是按T568B排序。

这里找了一张网上的图对比两种不同的接线方法在网线上的不同接入方式:

直连和交叉接线的区别

实际上没有本质区别,只是不同的网线适应不同的场景而已。具体的使用场景可以看上面截图的内容,这里简单举例说明。

直连线用于两种不同的设备之间:

  1. 主机和集线器或者交换机连接。
  2. 路由器交换机和集线器。
  3. 交换机使用的端口不同。

交叉线使用同类型设备,这里只要记住交叉线适用于相同类型的设备。

这里记住一条规则:同种设备用交叉,不同设备用直连。

然而随着技术的发展和迭代现代设备对于网线接口的依赖其实并不是特别强,同种设备使用直连线也是可以兼容的,所以上面的这条规则只能作为一个参考。

交换机信号传输

交换机通常属于OSI模型的第二层(数据链路层),交换机的工作依赖于对MAC地址的识别。

交换机设计是将网络包原样转发到目的地,目的是为了实现远距离的网络包传输而不让数据失真。

因为需要交换数据,交换的接口和 PHY(MAU)模块也是以 MDI-X 模式进行连接的,当网络包进入接口之后首先是把信号翻译为交换机通用格式,接着是使用MAC模块部分对于网络包进行解析,并且使用包末尾的 FCS 校验错误。

交换机看似和网卡的工作类似实际上有着类似的作用,通过查询MAC地址以及端口查找对应的目标地址,然后转发到下一个离目标地点更近的地址。

交换机的端口不核对接收方 MAC 地址,而是直接接收所有的包并存放到缓冲区中,而之前章节提到过网卡在生产出来的之后本身就自带唯一的MAC地址并且收发信息都需要核对MAC地址。

显然网卡和交换机还是有不小差别的,因为交换机端口的 MAC 模块不具有 MAC 地址

下面的内容是关于交换机工作较为详细解释,整个工作简而言之:交换机根据 MAC 地址表查找 MAC 地址, 然后将信号发送到相应的端口。

当交换机从其某个端口收到一个数据包时,先读取包头中的源MAC地址(即发送该数据包的设备网卡的MAC地址),将该MAC地址和端口对应起来添加到交换机内存里的地址表中;然后再读取包头中的目的MAC地址,对照内存里的地址表看该MAC地址与哪个端口对应。

如果地址表中有该MAC地址的对应端口,则将该数据包直接复制到对应的端口上,如果没有找到则将该数据帧作为一个广播帧发送到所有的端口,对应的MAC地址设备会自动接收该帧数据,同时交换机将接收该帧数据的端口与这个目的MAC地址对应起来,最后放入内存中的地址表中。

快速理解交换机的特点:具备大部分网卡特性的以太网数据传输设备

这里回顾之前章节介绍的FCS内容。

FCS:检查包传输过程中因噪声导致的波形紊乱、数据错误,它是一串 32 比特的序列,是通过一个公式对包中从头到尾 的所有内容进行计算而得出来的。 具体可以参考网络包的结构示意图。

交换机内部结构

MAC地址维护

交换机基本工作是查找核对MAC地址以及维护 MAC地址表的工作,MAC地址的维护主要有下面两个细节:

  1. 发送方 MAC 地址以及其输入端口的号码写入 MAC 地址表中。MAC地址表的数据非常庞大但是端口的数量有限,为了快速的查找和管理,只要某个设备发送过网络包,它的 MAC 地址就会被记录到地址表中,这种结构和缓存类似。
  2. MAC地址表通常是“实时更新”的,目的是为了防止设备移动问题。由于现代移动设备会频繁的切换网络环境和端口状态,交换机为了适应发送方频繁“变更”端口需要及时删除地址表的映射记录。

另外需要补充说明和大多数的缓存特征相同,MAC地址的删除不是实时的,所以有时候数据包可能会发给之前的,但是这种事情通常不需要担心也比较罕见,通常重启交换机并且刷新掉MAC地址和端口映射即可,交换机会自行更新或删除地址表中的记录,不需要手动维护

交换机特殊处理

下面介绍交换机的几种特殊情况。

第一种是如果发现网络包的发送方和目标地址是同一个映射端口,这种情况下目标机器会收到两个重复的包导致无法通信,所以这种网络包交换机收到之后直接丢弃。

另一种情况地址表中找不到指定的 MAC 地址,这种情况可能是目标地址从来没有在互联网中进行过交互,或者是设备长时间不工作地址被交换机删除。

这种情况下交换机会使用广播发给所有的网络设备直到找到应答方,一旦接收到应答就会存储下MAC地址和映射端口,这种设计本身也和以太网最初的设计考虑一致。

最后一种是如果接收方 MAC 地址是一个广播地址,那么交换机会将包发送到除源端口之外的所有端口。

全双工协议

全双工协议存在于交换机当中,集线器不具备这样的特点,集线器由于多个信号传入会导致信号碰撞是半双工协议的。

交换机是全双工协议的,所以在传输过程中不管有没有网络包交换机也可以自己进行数据的收发操作。在全双工的模式下信号碰撞不会发生,因此这种模式下也不需要碰撞检测。

全双工协议出现的早期需要人为的手工切换,当然随着技术发展后来出现了工作模式的自动切换。

另外在早期为了保证通信正常,在以太网的架构如果没有信号传输,会默认填充脉冲信号在网络中不断流过,为了兼容新老设备的传输速率, 脉冲信号的传输会使用“木桶效应”的短板自动兼容完成全双工协议的脉冲信号传输。

最后由于交换机支持全双工的协议,当端口不需要传输数据的时候可以实现多个端口的转发操作,关于交换机的更多内容可以查阅资料了解。

路由器信号传输

数据由交换机发送出来之后,信号会传输到路由器。

路由器是基于 IP 设计的,而交换机是基于以太网设计的,虽然看上去工作是类似的查表判断包应该发往那里,但是由于设计初衷的不同,所以还是存在很大的差别。

路由器的内部结构重点关注转发模块端口模块,其中转发模块负责判断包的转发目的地,端口模块负责包的收发操作,有点类似协议栈的IP模块和网卡之间的关系。

路由器支持多种协议,只要端口模块安装了相关协议就可以支持信号传输,通过不同的端口完成不同协议的工作,路由器的各个端口都具有 MAC 地址和 IP 地址。

以太网端口为例, 路由器的端口具有 MAC 地址 ,因此它就能够成为以太网的发送方和接收方,此外端口还具有 IP 地址,所以它可以充当网卡使用。

路由表的信息

在路由器中的表信息被叫做路由表,查表判断转发目标的基本思路和交换机是类似的,但是工作方式不太一样。

主要的区别可以从路由表的设计上进行对比,这里需要再次用上子网掩码的相关知识,首先这里可以看到目标地址存储的主机号部分为0,所以这里明显存储的是目标IP的子网。

路由器会忽略主机号,只匹配网络号,只要接收到的IP网络号一致,则可以认为是符合同一个方向传递来的数据。

为了提高路由器中路由表的地址管理效率,有时候目标地址实际子网掩码和子网掩码并不是完全匹配的,这里可以类比DNS对于IP地址的维护。

路由器在维护目标地址和子网掩码的时候,路由聚合会将几个子 网合并成一个子网, 并在路由表中只产生一条记录,比如10.10.1.0/24、10.10.2.0/24、10.10.3.0/24这三个地址虽然不属于同一个子网,但是可以通过 10.10.0.0/16(注意网络号变化为16位)这样的形式类似对于掩码进行二次掩码匹配的操作。

所以路由表的子网掩码列只表示在匹配网络包目标地址时需要对比的比特数量,利用路由聚合可以减少不必要的查表和提高路由效率。

最后是路由表信息的维护工作,主要方式是下面两种:

  • 由人手动维护路由记录 。
  • 根据路由协议机制, 通过路由器之间的信息交换由路由器自行维 护路由表的记录。

路由器包收发操作

信号传输到接口部分,接口的PHY模块和MAC模块把信号进行转化翻译,末尾同样需要校验FCS。

接着再检查MAC地址,路由器的端口同样都具有 MAC 地址, 只接收与自身地址匹配的包,遇到不匹配的包则直接丢弃。其中的接收方 MAC 地址就是路由器端口 的 MAC 地址。

这里比较容易误解的是接收方的地址可能被认为主机的地址,其实是路由器的接收端口的MAC地址,因为网络包是发给路由器的,再由路由器查表发给具体的主机。

路由表查表操作

路由表的查表规则是按照匹配的最长网络号比特殊进行匹配,因为网络号越多证明子网掩码的范围越小子网所覆盖的主机也越少,越有可能找到对应的主机地址。这样的匹配规则也被叫做 最长匹配规则

对于服务器这种通常具备固定公网IP的设备在路由表上会有诸如192.168.1.10/255.255.255.255的表现形式,这样的IP在查找的时候可以按照最长匹规则进行匹配。

注意如果在路由表中无法找到匹配的记录,路由器会丢弃这个包,并通过 ICMP消息告知发送方。为什么会直接丢弃包呢?这是因为互联网多设备实在是过于庞大数量过多,查询代价是难以估计的。

默认路由选择

所有的转发操作都要匹配路由表显然是不现实的,所以在路由器中默认配置了0.0.0.0 让任何地址都可以进行匹配到,另外这一行配置也被叫做默认网关

在计算机的 TCP/IP 设置窗口中也有一个填写默认网关的框,表示计算机上 也有一张和路由器一样的路由表,其中默认网关的地址就是我们在设置窗口中填写的地址。

在IPV4中,0.0.0.0地址被用于表示一个无效的,未知的或者不可用的目标。

  • 在服务器中,0.0.0.0表示是本机上的所有IPV4地址,如果一个主机有两个IP地址,比如192.168.1.1 和 10.1.2.1,并且该主机上的一个服务监听的地址是0.0.0.0,那么通过两个ip地址都能够访问该服务。
  • 在路由中,0.0.0.0表示的是默认路由,即当路由表中没有找到完全匹配的路由的时候所对应的路由。

0.0.0.0的主要用途:

  • DHCP分配前表示本机。
  • 用作默认路由表示任意主机。
  • 用作服务端表示本机的任意IPV4地址。
  • 表示目标机器不可用

路由器和交换机的差别

最后我们来看路由器和交换机的差别

  1. 交换机通过MAC头部接收方MAC地址判断转发目标,路由器则通过IP模块判断IP地址来确定转发目标。
  2. 交换机在地址 表中只匹配完全一致的记录,而路由器则会忽略主机号部分,只匹配网络号部分。

包的有效期

路由器发送网络包之前,还有一些工作要做:更新IP头部的TTL字段,TTL指的是包的有效期,如果这个值为0表示转发,比如发送方在发送包时会将 TTL 设为 64 或 128, 也就是说包经过这么多 路由器后就会“寿终正寝”。这个机制的作用是防止包无限转发而设计的。

分片功能拆分大网络包

这里的分片和TCP拆分数据是不同的,TCP 拆分数据的操作是在将数据装到包里之 前进行的,换句话说拆分好的一个数据块正好装进一个包里。而IP分片是把合成的一个包再一次进行分片的操作。

决定IP模块是否分片主要限制是MTU参数以及输出端口支持的MTU大小,如果输出端口太小就需要按照限制的大小对于包进分片,如果查询标志字段发现不能分片, 那么就只能丢弃这个包, 并通过 ICMP 消息通知发送方。

需要注意分片之后每一份数据前面会加上 IP 头部,大部分情况下添加头部都是相似的,只是=其中有部分字段需要更新,这些字段用于记录分 片相关的信息。

路由器的发送操作

路由器判断下一个转发目标的方法如下:

  • 如果路由表的网关列内容为 IP 地址, 则该地址就是下一个转发目标。
  • 路由器使用 ARP 来查询下一个转发目标的 MAC 地址。
  • 如果路由表的网关列内容为空,则 IP 头部中的接收方 IP 地址就是下一个转发目标。

这几个步骤详细描述,可以获得下面的过程:

  1. 首先判断MAC地址,取出MAC头部判断路由表的网关,如果网关为空,则 IP 头部中的接收 方 IP 地址就是要转发到的目标地址。
  2. ARP广播协议根据IP找到对方MAC地址,并且存储未接收方MAC地址。
  3. 填写输出端发送方 MAC 地址字段, 这里填写输出端口的 MAC 地址还有一个以太类型字段,填写 0080(十六进制)。
  4. 把网络包转为电信号传输,如果信号碰撞则进行重发,如果非全双工模式则等待线路没有信号进行传输,否则无需确认是否有其他信号直接传输。
  5. 发送的包通过交换机传给下一个路由器,然后路由器根据规则层层转发到达目的地。

整个过程有点类似现代快递的传输,由一个站点找到下一个站点,最后到达目的地址。交换机的作用也非常明显,他和路由器属于分工合作,IP (路由器)负责将包发送给通信对象这一整体过程,而其中将包传输到下一个路由器的过程则是由以太网(交换机)来负责的。

路由器在这里是方向盘的角色,而交换机更像是开车的人。

路由器其他功能

IP地址的长度为32个bit,所以很多情况下不同局域网的用户可能有相同的I P。为了解决相同IP在互联网中“共存”问题,需要采用固定地址的分配方式区分内外网。

通常我们把给公司内部使用的网络叫做私有地址,而固定提供对外访问的地址叫做固定地址。公有地址和私有地址的区别是私有地址在访问互联网的时候会进行转化并且只能在内网中进行直接通信,而这个转化机制比较关键,

地址转化

地址转换的基本原理是在转发网络包时对 IP 头部中的 IP 地址和端口号 进行改写。 具体可以看看下面的例子,在对外只能使用一个公有地址的情况下,可以用不同的端口号来区别内网中的 不同终端。

地址转换设备会从地址对应表中通过公有地址和端口号找到 相对应的私有地址和端口号,根据对应表查找私有地址 和公有地址的对应关系之后,再改写地址和端口号之后进行转发。

地址转化从表面上看同样类似委托操作,接收方的通信对象实际上是和地址转化设备完成。

改写端口号

改写端口号的意义是为了让一个公网地址可以对应更多的私有地址,对于一个大公司来说一个公网地址几万个端口以及是可以支持使用的。

此外如果是内网地址的通信在地址转化设备表中不存在也可以正常通信,因为转发设备本身的地址就是被用来改写的公网地址。

路由器包过滤

最后路由包的过滤,基本是是通过IP模块,MAC模块和TCP模块配合校验一个网络包请求是否合法。

包过滤的意义当然是为了保证网络安全,防止互联网伪造网络包进入内容破坏内网的系统应用。

当网络包通过互联网接入路由器之后,接下来的部分就是 ADS L或者FTTH的工作了,这部分内容主要为运营商的内容。

其他内容

集线器(repeater hub) 交换机(switching hub)虽 然名字差不多但内部结构完全不同,路由器早期效率实际上不如交换机,但是如果管路由器叫做hub 显然会让用户认为价钱昂贵并且难以接收,但是如果跟客户说接上网线就可以上网,情况就会变得不一样。

另外交换机的在后来的历史发展中发展出二层交换机,我们在小结中进行展示。从字面理解小型廉价的普及型产品一般叫交换机,大型的高性能产品一般叫二层交换机。

小结

下面是总结集线器、交换机和路由器分别是什么,接着是补充一部分交换机后续发展的内容。

集线器

集线器(即HUB,物理层设备)是一种将多条双绞线或光纤集合连接在同一段物理介质下的设备,通常工作在物理层(即OSI参考模型第一层),用于连接局域网段。

集线器拥有多个端口,当其中一个端口接收到信号后,会将衰减的信号整型放大,然后再将放大的信号广播转发给其他所有端口,以便局域网的所有段都可以看到数据包。在网络中,集线器充当着设备的公共连接点。

在OSI参考模型的底部。常用设备还包括网卡、集线器、中继器、调制解调器、网线、双绞线、同轴电缆。

交换机

交换机是一种用于光/电信号转发的网络设备,通常工作在数据链路层或网络层(即OSI参考模型的第二层和第三层),支持各种数据包协议。目前交换机类型繁多,如局域网交换机、以太网交换机等。

其中局域网交换机主要用于交换式局域网内进行数据交换,而以太网交换机主要用于以太网内进行数据传输。

在网络中交换机是用于局域网段之间过滤和转发数据包的设备。

路由器

路由器是连接Internet中各局域网、广域网的设备,通常位于两个或者多个网络连接的网关处,工作在网络层,用于实现两个局域网或两个广域网或一个局域网和互联网服务提供商之间的网络连接。

在路由器中通常存着一张路由表,它会根据信道的情况自动选择和设定路由,然后以最佳路径发送信号。另外,路由器支持Internet控制报文协议(即ICMP)等类似协议,可帮助IP主机、路由器之间传递控制消息,为任意两台主机之间配置最佳路由。

二层和三层交换机

二层交换机通常用于连接以太网中的网络设备和客户端设备,以识别与转发数据包中的MAC地址。但随着网络应用程序多样性的增加以及融合网络应用的发展,三层交换机的应用在数据中心,复杂的企业网络,商业应用乃至高级客户项目中蓬勃发展。

二层交换机工作于OSI模型的二层(数据链路层),故而称为二层交换机,主要功能包括物理编址、错误校验、帧序列以及流控。而三层交换机位于三层(网络层),是一个具有三层交换功能的设备,即带有三层路由功能的二层交换机,但它是二者的有机结合,并不是简单地把路由器设备的硬件及软件叠加在局域网交换机上。

二层和三层交换机的区别

二层和三层交换机之间的主要区别在于是否拥有路由功能。

二层交换机:属数据链路层设备,可以识别数据包中的MAC地址信息,根据MAC地址进行转发,并将这些MAC地址与对应的端口记录在自己内部的一个地址表中。

三层交换机:就是具有部分路由器功能的交换机,工作在OSI网络标准模型的三层:网络层,目的是加快大型局域网内部的数据交换,所具有的路由功能也是为这目的服务的,能够做到一次路由,多次转发。此外,三层交换机可以执行静态路由和动态路由

OSI参考模型

虽然OSI模型最初的设想很美好,然而实际上被TCP/IP网络模型替代,但是下面三层的内容基本是没有变化的,在学习了这一章的内容之后,我们对于整个互联网的架构应该有了更深入的了解。

《网络是怎么样连接的》读书笔记 - 服务器端的局域网中(四)

本章重点

  • 防火墙的地位作用以及现代主流的服务器部署方式。
  • 缓存服务器的作用以及部署方式。
  • 三种代理方式以及区别。
  • 内容分发服务是什么?缓存服务器不同部署方式的影响。

防火墙和网络访问

如果服务器不设置任何防护并且裸奔,很大概率受到网络攻击,现在公司基本都会使用防火墙 服务器的部署方式。还有一种是直接买服务器供应商也就是常见的上云,直接让专业的三方服务器管理进行防护。

防护网络攻击的手段目前主流的方式有三种,其中被使用最多也最有效的是包过滤

第一种方式为包过滤,包过滤非常简单,因为在网络包的头部包含了网络请求的所有信息,通过接收方 IP 地 址和发送方 IP 地址,我们可以判断出包的起点和终点。因为请求的终点是可以确定的,也就是WEB服务器,所以这之间加入防火墙来隔离异常请求。

第二种方式是使用端口的方式进行限制,防火墙控制某个端口的请求网络是否可以来放行不同IP进入不同端口的权限。

第三种是TCP层面的防护,TCP 在执行连接操作时需要收发 3 个包,第一个包通常使用其他端口,可以判断一定是在 Web 服务器 程序中特别设置过的,因此只要按照服务器的设置来调整防火墙设置即可,通常这个包中 TCP 控制位中 SYN 为 1,而 ACK 为 0。

其他的包中这些值都不同, 因 此只要按照这个规则就能够过滤到 TCP 连接的第一个包。因为WEB服务器发往互联网被阻断了,所以这样就实现了拦截,从反方向来看,第一个包是发往WEB服务器的,返回是从WEB返回的,所以互联网访问WE B是没有问题的。

最后这样就实现了“可进不可出”的效果,根据第三章讨论的地址转换的工作原理,当使用地址转换时,默认状态下是无法从互联网访问公司内网的,因此我们不需要再设置一条包过滤规 则来阻止从互联网访问公司内网。

最后需要说明包拦截过滤并不是防火墙特有的功能,而是路由器的包转发功能基础上附加的一种功能。

对于防火墙这种机制是典型的“攘外但是不能安内”的存在,意思是说虽然对外的敌人是拦截的,但是出现了防火墙无法防御的内鬼是解决不了的,所以针对防火墙无法处理的问题,又引申出几种处理方式:

  • 第一种是修复应用程序的BUG,这些BUG通常是技术人员在开发过程中没有考虑到的系统漏洞问题,这种问题是可以通过人为手段快速修复的 。
  • 第二种是用加一层的绝招,对于异常流量进行拦截,比如最为经典的DDos攻击,使用自身的防火墙显然是不行的,必须有外部监控防护服务器进行保护。

负载均衡

单机的负载均衡是没有意义的伪负载均衡,下面讨论的都所有情况都是在多物理或者多主机映射的虚拟机的情况进行介绍。

负载均衡通常会使用缓存服务器,缓存服务器是一台通过代理机制对数据进行缓存的服务器。

缓存服务器位于web服务器和客户端之间具备对于WEB的中转功能,主要工作非常简单就是把WEB服务器返回的数据缓存在磁盘中序列化存储,目的是提高WEB服务器的响应速度。

缓存服务器最大的问题是服务器更新数据之后缓存可能还没同步而看到旧数据,为此缓存提供了缓存最大的保存时间以及用户访问隔离的特性,简单理解就是针对不同的客户端看到的内容是不同的,不过从服务器的角度看与之交互的是缓存服务器。

判断什么时候需要直接返回服务器数据而不是缓存数据,一种简单的方案是检查客户端的网络报文信息变动,并且自己在返回的时候也要告知自己是缓存还是服务器数据。

最后缓存的最大问题是缓存命中率的问题,但是此问题不在本章科普范围之内不做过多介绍。

代理处理

正向代理:正向代理刚刚出现的时候,其目的之一就是缓存,这个目的和服务器 端的缓存服务器相同。当设置了 正向代理时,浏览器会忽略网址栏的内容,直接将所有请求发送给正向代 理。请求消息的内容也会有一些不同。

正向代理是最为简单直观的代理方式,具备有下面的特点:

1、访问内部节点:通常使用跳板作为进入内网的工具。

2、加快访问速度:代理服务器可以缓存内网资源,用户请求已缓存资源时,直接发送给用户,比如国内阿里云的MAVEN仓库。

3、访问控制:代理服务器可以设置访问权限,控制外部主机对内网资源的访问。简单的权限控制防止外部访问内部网络。

一些好用的代理工具:

1.reDuh源码https://github.com/sensepost/reDuh

2.reGeorg源码https://github.com/sensepost/reGeorg

3.tunna 源码 https://github.com/SECFORCE/Tunna

反向代理

正好与正向代理相反,对于客户端而言代理服务器就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端。

反向代理服务器的作用:

集群式部署实现负载均衡,CDN技术(构建在数据网络上的一种分布式的内容分发网),前端服务器,Nginx(异步框架的网页服务器)等。

1、用户访问web服务时,并不知道访问的是代理服务器,代理服务器就是web服务器。

2、加快访问速度,和正向代理一样可以缓存内网数据。

3、实现负载均衡,降低单个服务器的负担,提高整体资源的利用率。

透明代理

意思是客户端根本不需要知道有代理服务器的存在,它修改你的请求报文,并会传送真实IP。注意加密的透明代理则是属于匿名代理,意思是不用设置使用代理了。对于整个请求来说是无感知的。也因为是无感知的,所以透明代理不能和反向代理兼容。

透明代理的作用:

1、实践例子为当下很多公司使用的行为管理软件。

2、客户端访问web并不知道是通过代理服务器访问的。

3、防火墙设置透明代理,当PC让代理服务器请求web页面时,代理服务器返回页面数据。

内容分发服务

缓存服务器部署在不同的地方,其效果会完全不一样。关于部署的不同方式可以直接看下面的图,这里主要记录第三种部署方式的利弊。

第三种部署方式是和网络运营商签约的方式缓存服务器就近部署(类似CDN),当然这样的开销显然很大,所以在此之上也有中间商插入专门干这些事情,这些运营商被叫做CDSP( Content Delivery Service Provider,内容分发服务运营商)。

这些运营商会和主要的互联网供应商签约,并部署很多台缓存服务器,缓存服务器可以缓存多个网站的数据,因此 CDSP 的缓存服务器就可 以提供给多个 Web 服务器的运营者共享。

如何让客户端找最近的服务器

答案是是像负载均衡一样用 DNS 服务器来分配访问,对于DNS向Web返回IP的同时返回一些额外的信息。

而对于如何估算出客户端和就近服务器的距离,可以通过把所有的路由放到路由表中,可以通过路由次数的方式判断距离,虽然不一定完全一致,但是可以以较大的精度确定位置。

其他的办法是通过重定向的方式查找最近的缓存服务器,重定向服务器通过收集了来自各个路由器的路由信息,并根据这些信息找到最近 的缓存服务器。

除了收集路由信息,重定向也可以返回一个通过网络包往返时间估算到缓存服务器的距离的脚本, 通过在客户端运行脚本来找到最优的缓存服务器。

缓存更新的影响

缓存更新会影响缓存服务器的效率,所以更新方法非常重要。

比较常见的更新方式是每次原始服务器更新就立刻通知缓存服务器,让其一直保持最新状态,这个功能的执行者就是内容分发服务。

除了编写静态页面之外,还以一种方式是选择不保存页面而是将网页的动态内容和静态内容分离,比如图片服务器、文件服务器等等。

总结

这一章算是比较科普向的一章,其实也算是可看可不看的类型,个人认为重点是代理处理的部分,了解三种代理方式。

而负载均衡的内容则需要深入学习Nginx的相关内容,本章讲述的内容有些太浅了。

总之是轻松加愉快的一章内容。

《网络是怎么样连接的》读书笔记 - WEB服务端请求和响应(五)

本章重点

客户端和服务端的区别以及客户端响应的连接过程。

客户端和服务端的区别

服务器的分类和功能种类有很多,但是网络相关的部分, 如网卡、协议栈、Socket 库等功能和客户端却并无二致。

另外我们可以回顾第一章笔记中介绍了关于互联网的历史部分,网络自诞生开始就是为了军事通信,意味着最好是在数据收发层面不需要区分客户端和服务器,而是能够以左右对称的方式自由发送数据。

所以我们常说的客户端和服务端仅仅是从发送者和接受者的角度来区分,如果服务器发送请求到客户端,也可以认为服务器本身是“客户端”。

关于服务端和客户端我们从Socket库调用上查看两者差别:

客户端的数据收发需要 经过下面 4 个阶段。

(1)创建套接字(创建套接字阶段)

(2)用管道连接服务器端的套接字(连接阶段)

(3)收发数据(收发阶段)

(4)断开管道并删除套接字(断开阶段)

服务器是将阶段(2)改成了等待连接

(1)创建套接字(创建套接字阶段)

(2-1)将套接字设置为等待连接状态(等待连接阶段)

(2-2)接受连接(接受连接阶段)

(3)收发数据(收发阶段)

(4)断开管道并删除套接字(断开阶段)

连接过程

下面和第二章介绍客户端连接类似,介绍服务端连接的步骤。

首先调用 bind 将端口号写入套接字中,并且要设置端口,之后协议栈会调用accept连接,注意这时候包可能是没有到来的,如果包没有到来服务端会阻塞等待客户端的请求,一旦接收到连接就会开始响应并且进行连接操作。

接下来协议栈会给等待连接的套接字复制一个副本, 然后将连接对象等控制信息写入新的套接字中,为什么这里要创建副本简单解释一下,因为如果直接使用原有的套接字连接,那么当新的客户端请求过来,就必须要再次创建新的套接字然后再次进行连接。使用复制套接字的方式,原有的套接字依然可以完成等待连接的工作,和新建的套接字副本是没有关联的。

创建套接字除了复制套接字这个特点外,还有一个是端口号的使用,因为一个套接字需要对应一个端口号,但是需要注意新创建的套接字副本必须和原来的等待连接的套接字具有相同的端口号,原因是防止类似客户端本来想要连接 80 端口上的套接字, 结果从另一个端口号返回了包这样的情况。

针对这个问题,服务端的套接字除了确定端口之外,还需要带上IP信息和客户端的端口号信息,最终依靠下面四个变量来确定和哪一个套接字交互。

  • 客户端 IP 地址
  • 客户端端口号
  • 服务器 IP 地址
  • 服务器端口号

从上面这幅图可以看到,服务端可能会在一个端口上创建副本绑定很多个套接字,但是客户端的端口是完全不同并且随机的,同时IP地址也不一样,所以可以确定套接字之间是不会存在冲突的。

套接字准备完成之后,接着是对于网络包进行FCS 的校验,当 FCS 一致确认数据没有错误时,接下来需要检查 MAC 头部中 的接收方 MAC 地址,看看这个包是不是发给自己的,之后网卡的 MAC 模块将网络包从信号还原为数字信息, 校验 FCS并存入缓冲区。

网卡收到消息之后,接着是执行中断处理机制告知CPU开始进行网卡的数据处理,关于中断处理的内容可以通过的另一本书《Linux是怎么样工作的》了解CPU的中断处理机制了解整个执行过程,之后网卡驱动会根据 MAC 头部判断协议类型,并将包交给相应的协议栈。

为什么还要使用描述符呢?

这里回顾一下描述符的内容,描述符指的是在创建套接字之后,服务端需要返回给客户端一条标识信息,目的是告知客户端自己是谁,协议栈也需要返回描述符用于标识是哪一个套接字在进行传数据。

这里可以简单理解为我们在网络聊天的时候虽然知道对方是谁和自己聊天,但是如果对方没有“开摄像头”告诉你我是本人,很有可能是别人伪装你认识的人在和你聊天。而我们知道对方是本人在和我们聊天也是因为对方的一些“性格”所以了解。

当网络包转交到协议栈时,IP 模块会首先开始工作检查 IP 头部。IP 头部主要是检查规范,检查双方的IP地址,确认包是不是发给自己的,确认包是发给自己的之后,接下来需要检查包有没有被分片,然后检查 IP 头部的协议号字段,并将包转交给相应的模块。

IP模块接收操作小结

协议栈的 IP 模块会检查 IP 头部:

(1)判断是不是发给自己的;

(2)判断网络包是否经过分片;

(3)将包转交给 TCP 模块或 UDP模块。

根据IP头部的协议找到06发现是TCP协议判断之后的内容是TCP模块的包,此时检查控制位 SYN 是否为 1,这也表示这是一个发起连接的包。

TCP 模块会执行接受连接的操作,此时需要同时检查端口是否存在对应的套接字连接,如果没有则会向客户端返回错误通知的包,如果存在则复制套接字的副本,并且双方需要互相交换信息存储在套接字的缓冲区,这时候服务器端的程序应该进入调用 accept 的暂停状态,当新套接字的描述符转交给服务器程序之后,服务器程序就会恢复运行。

接下来是TCP模块处理数据部分,首先是检查收到的包对应哪一个套接字,这里对应之前说的四种信息判断唯一套接字,因为服务端的一个端口可能绑定非常多的客户端端口。

对上套接字之后,TCP 模块会对比该套接字中保存的数据收发状态和收到的包的 TCP 头部中的信息是否匹配,比如检查收到的包序号是否匹配等,如果数据确认无误,将会生成对应的应答头部并且计算ACK号码,然后自己再生成一个序号返回给客户端。

收到的数据块进入接收缓冲区,意味着数据包接收的操作告一段落了,之后传递数据会通过read等待然后直接交给应用程序处理了,最后应用程序根据请求的内容向浏览器返回相应的数据。

TCP 模块操作小结

(1)根据收到的包的发送方 IP 地址、发送方端口号、接收方 IP 地址、接收方端口号找到相对应的套接字;

(2)将数据块拼合起来并保存在接收缓冲区中;

(3)向客户端返回 ACK。

最后是断开操作,断开操作的主要区别在HTTP协议上,HTTP1.0需要服务器发起,而HTTP1.1当中断开由客户端开始。

为什么HTTP1.0和HTTP1.1在断开的时候有如此差别,可以看下面的补充内容,这部分内容来自网络:

http1.0

  • 如果在HTTP请求中携带content-length,此时请求body长度可知,客户端在接收body时就可以依据这个长度来接受数据。接受完毕后,就表示这个请求完毕了。客户端主动调用close进入四次挥手。
  • 反之,如果不带content-length ,则body长度不可知,客户端一直接受数据,直到服务端主动断开。

http1.1

  • 如果HTTP请求中携带content-length,此时body长度可知,则由客户端主动断开。
  • 如果发现HTTP中带Transfer-encoding:chunked body会被分成多个块,每块的开始会标识出当前块的长度,body就不需要通过content-length来指定了,但依然可以知道body的长度,此时客户端主动断开。
  • 如果请求不带不带Transfer-encoding:chunked且不带content-length,客户端接收数据,直到服务端主动断开连接。

也就是说如果能够有办法知道服务器传来的长度,都是客户端首先断开。如果不知道就一直接收数据直到服务端断开。

总结

这一章节的内容更像是对于前面几章内容的查漏补缺,以及对于之前内容做了一整体的简单复习,在后半部分介绍了关于应用程序返回数据的介绍,这部分比较偏向WEB 所以就没有收录到笔记当中了。

整体看下来这本书需要重点学习的是前面的三章内容,后面两章内容更像是理论知识的补充以及对于前面内容的补充。

对于最后一章服务端响应数据的细节建议和客户端结合学习,效果会事半功倍。

《网络是怎么样连接的》读书笔记 - ADSL

简介

整个互联网的体系架构看起来复杂,实际上基本的工作方式单调而乏味,就是从一个路由器到下一个路由器。

这一部分介绍有关ADSL的接入方式,如果是90后基本都很熟悉以前通过拨号上网的方式接入互联网,对于用户来说是打个电话就可以上网,但是内部的工作流程其实还是比较复杂的。

术语介绍

ADSL: Asymmetric Digital Subscriber Line,不对称数字用户线。它是一种 利用架设在电线杆上的金属电话线来进行高速通信的技术,它的上行方向 (用户到互联网)和下行方向(互联网到用户)的通信速率是不对称的。

传输过程图

ADSL传输可以总结下面的简化图,说实话第一眼看过去确实很复杂,所以接下来的传输部分将会按照步骤进行拆解。

传输过程

从全局来看,整个过程是用户发出网络包通过用户端的电话局,然后到达网络运营商(ISP,互联网服务提供商),最后通过接通路由器上网。

下面

接通路由器

第一步是接通路由器,这一步的主要操作是根据包 IP 头部中的接收方 IP 地址在路由表的目标地址中进行匹配,找到相应的路由记录后将包转发到这条路由的目标网关。

整个流程图在书中已经画的十分清晰了,如果无法理解这些设备干啥的,只要模糊理解大概做了什么事情在那个位置即可。

虽然整个工作流程和以太网以及路由器的工作方式类似,但是实际上还是有一些区别的,主要区别是在头部的网络包的头部部分会额外添加一些东西,MAC 头部、PPPoE 头部、PPP 头 部 总共3种头部。

ADSL Modem

完成互联网接入路由器操作之后,接着请求发送给ADSL Modem,这里可以看到数据被拆分为一个个的小格子,这些小格子被称为信元

信元同样包含头部和数据部分,整个拆分过程类似TCP/IP 把数据拆包,拆分完成之后信元需要应用于一种叫做ATM的通信技术完成通信。

ATM采用面向连接的传输方式,将数据分割成固定长度的信元,通过虚连接进行交换。ATM集交换、复用、传输为一体,在复用上采用的是异步时分复用方式,通过信息的首部或标头来区分不同信道。

转化为信元之后ADSL Modem 会把数据转为圆滑波形的信号表示0和1 ,这种技术被称为调制,ADSL Modem振幅调制(ASK)相位调制(PSK)相结合的正交振幅调 制(QAM) A方式。

如果不太清楚这两个是啥也不重要,其实主要是电子信号波的不同处理方式罢了。

  • 振幅调变Amplitude ModulationAM),也可简称为调幅,是在电子通信中使用的一种调变方法,最常用于无线电载波传输信息。
代码语言:txt复制
振幅调变简单的把高振幅为1,低振幅为0,由于调幅是最早期的调变方式,他的优点是容易恢复讯号,但是因为信号终究会随着距离衰减,所以调幅需要控制传输的级别,级别过多容易出错。
  • 相位调制,这是一种根据信号的相位来对应 0 和 1 的方式,Modem 会产生一个一定周期振动的波,一个周期是360度,可以看作是一个完整的圆被划分为两个部分,相位调制和调幅类似,也可以通过变化周期也就是角度来控制频率。

为什么不像互联网一样使用使用方波信号的0和1 表示? 1. 方波传输容易失真,距离延长错误率会提高。 2. 方波是宽频频段,如果频率过宽会产生难以控制的噪声

正交振幅调制实际上就是把上面两种调制方式融合在一起,最后就成为了ADSL Modem的调制方式,最后形成下面这张图:

通过这样灵活的波段方式,ADSL通过给噪声大的波段更少的Bit和噪声小的波段更多的比特进行灵活控制。

分离器

信元数据转为电信号之后是把数据发给分离器,分离器看起来像是出网的时候进行分离,实际上工作是在入网的时候。

因为电信号和电话的信号一起传输给另一端的,如果不分离两种信号那么电话听到的将会全是噪音,十分影响用户体验。

分离器的工作原理非常简单,简单来讲就是屏蔽ADSL所使用的高频信号而已,电话信号将会传到电话机,而ADSL的信号传给另一端的ADSL Modem

从另一个角度来说分离器另一个作用是防止电话信号传到ADSL Modem那边,之所以要这样做是拿起话筒和放下话筒的时候电话信号的传输路径会出现调整,线路状态转变容易导致ADSL通信发生重连的问题。

DSLAM和BAS

信号通过配线盘接收到信号之后毫无疑问是把信号翻译回信元,翻译工作交给 DSLAM 设备完成。

DSLAM 设备相当于多个ADSL Modem捆到一起的设备,获取到信元之后数据进入到BAS包转发设备,BAS这个暂时抽象看作路由器即可,他和DSLAM 具备兼容的ATM 接口,主要的工作是负责把信元翻译成原始包。

这里可能会有疑问为什么不让 DSLAM 自己直接干这件事?这是因为DSLAM为了接受信元就需要做十分大量的工作,如果再让他负责翻译很容易造成职责捆绑过多出现问题,通用面对复杂的互联网更要小心职权划分。

数据进入倒BAS之后,接下来的工作是把原始数据一步步“解套”,比如把头部的MAC和PPPPoe头部丢弃,只保留PPP部分和后面的真实包(IP和数据包),因为他们工作已经完成了。

接下来BAS会找这个包所属的隧道并给这个包打上头部标记送走,隧道的出口就是隧道专用的路由器,送达之后同样是丢弃头部取出最终的IP模块信息。

在这之后就是传统的接入互联网的部分了,不得不说以前上网是非常麻烦的并且价格昂贵,个人小时候也只在亲戚家看过这种拨号上网的方式(自己家里的网络是接其他家路由器蹭的)。

以太网传输PPP消息

ADSL 和 FTTH 接入方式需要为计算机分配公有地址才能上网。

PPP大部分情况其实用到的功能很少,它的主要作用是方便运营商进行快速切换,但是PPP又无法直接用于ADSL和FTTH,所以这里绕弯的方式进行了处理。

由于PPP本身不符合以太网的传输协议,通常需要另一种协议进行适配,这种协议叫做HDLC协议,但是PPP如果使用HDLC协议,又会导致ADSL和FTTH无法接入。

所以要找别的方式对于以太网进行包装,另外需要注意以太网的设计和HDLC协议是不互通的,一番波折之后以太网找到了PPPoE互通。

这一部分理解可能会比较复杂,实际上按照设计模式的理解就是桥接和适配的过程,总之互联网的难题总是可以尝试加一层去解决,这里的方案也是类似的。

通过PPPoE互通之后,ADSL和FTTH就实现了拨号上网的方式。这里需要记住PPPoE 是将 PPP 消息装入以太网包进行传输的方式,换种方式说可以称PPPoe作为以太网上的PPP协议。

补充

HDLC(High-Level Data Link Control,高级数据链路控制),是链路层协议的一项国际标准,用以实现远程用户间资源共享以及信息交互。HDLC协议用以保证传送到下一层的数据在传输过程中能够准确地被接收,也就是差错释放中没有任何损失,并且序列正确。HDLC协议的另一个重要功能是流量控制,即一旦接收端收到数据,便能立即进行传输。

HDLC协议由ISO/IEC13239定义,于2002年修订,2007年再次讨论后定稿。在通信领域中,HDLC协议应用非常广泛,其工作方式可以支持半双工、全双工传送,支持点到点、多点结构,支持交换型、非交换型信道。 1

PPPoE(英语:Point-to-Point Protocol over Ethernet),以太网上的点对点协议,是将点对点协议(PPP)封装在以太网(Ethernet)框架中的一种网络隧道协议。由于协议中集成PPP协议,所以实现出传统以太网不能提供的身份验证、加密以及压缩等功能,也可用于缆线数据机(cable modem)和数位用户线路(DSL)等以以太网协议向用户提供接入服务的协议体系。 本质上,它是一个允许在以太网广播域中的两个以太网接口间建立点对点隧道的协议。

PPPoE的特点

PPPoE具有以下特点:

功能上:

  1. PPPoE由于集成了PPP协议,实现了传统以太网不能提供的身份验证、加密以及压缩等功能。
  2. PPPoE通过唯一的Session ID可以很好的保障用户的安全性。

应用上:

  1. PPPoE拨号上网作为一种最常见的方式让终端设备能够连接ISP从而实现宽带接入。
  2. PPPoE可用于缆线调制解调器(Cable Modem)和数字用户线路(DSL)等以太网线,通过以太网协议向用户提供接入服务的协议体系。

总而言之,PPPoE技术将以太网技术的经济性与PPP协议的可管理控制性结合在一起,提供接入互联网的功能。对于运营商来说,它能够最大限度地利用电信接入网现有的体系结构,利用现有的拨号网络资源,运营和管理的模式也不需要很大的改变;对于用户来说,使用感与原来的拨号上网没有太大区别,较容易接受。

隧道接通运营商

BAS 除了作为用户认证的窗口之外,还可以使用隧道方式来传输网络包,所谓的隧道就像是TCP的连接一样,数据从一方可以直接发往另一方,在互联网传输则是用户端直接接入到运营商。

实现隧道的方式比较多,比较常见的方式有下面几种:

  • 使用TCP的方式,需要依赖两端的隧道路由器进行TCP连接操作,然后网络包数据传输就变为TCP连接传输数据一样简单。
  • 还有一种常见的方式是把包含头部在内的整个网络包装到另一个包里面,其实说白了还是再包一层。

接入网的工作流程

ADSL接入网的工作重点包含下面几个部分:

  • 互联网接入路由器通过 PPPoE 的发现机制查询 BAS 的 MAC 地址。
  • BAS 下发的 TCP/IP 参数会被配置到互联网接入路由器的 BAS端的端口上,这样路由器就完成接入互联网的准备了。
代码语言:txt复制
 用户认证和配置下发,这两个重点第一点是保证用户路由器安全连接互联网,另一点是让BAS端可以认识用户,同时需要给路由器分配公网地址和默认网关:
代码语言:txt复制
-   CHAP:对于密码进行加密,相对安全。
-   PAP:不加密裸连方式,在ASDL的连接方式中容易被窃取,光纤传输就没这个问题。但是不推荐这样的加密方式路由器会选择默认路由,按照默认路由的网关地址转发,BAS告诉请求方路由器的这个地址怎么来的,注意这里包转发规则按照 

一对一连接

互联网接入过程不一定需要头部,如果可以确定是两个路由器点对点一对一的连接,为了保证公网IP的可用性,BAS可以不分配IP地址链接给路由器,这种方式被叫做无编号。

看起来不分配IP的方式挺玄乎,实际上它只是不使用自己的IP而是“借用”另一端口的IP为自己所用。同时这种连接方式是有限制的。使用无端口的模式限制如下:

  • 接口必须点对点连接
  • 串口两端接出的局域网接口满足下面条件:
    • 相同主网的不同子网掩码必须相同
    • 不同主网缺省掩码

私有地址转公有地址

之前说过路由器和BAS的连接必须要由BAS提供公网IP,但是实际上路由器在转发网络包的时候其实还需要做一步地址转化的操作。

如果把公有地址分配给路由器,那么计算机应用程序发送请求就必须把私有的地址转为公有地址传给BAS,这样BAS才能识别请求。

那么公网地址和IP可以分配给路由器,自然也可以分配给计算机,所以如果使用原始的上网方式不使用路由器上网则计算机直接获得IP。

PPPoA

PPPoA和PPPo E的主要区别在发送网络包的头部处理的时候,PPPoA 不需要添加MAC头部和PPPoE 头部,而是直接把包装入信元当中。但是因为PPPoA 的限制,使得计算机和路由器必须要和ADSL Modem一体,这里就涉及一体化的操作,具体的一体化方式有下面两种:

  • 第一种是ADSL Modem和USB接口连接起来,但是最终没有普及
  • 第二种方式是ADSL Modem 和路由器整合为一台设备,实际上就是PPPoE 直接使用路由器上网。所以第二种方式获得广泛普及。

PPPoA和PPPoE的其他区别体现在MTU的大小上,因为PPPoE多出了PPPoE和PPP头部,这样传输数据的实际网络包的部分就是缩小,而PPPoA就没有这个问题。

但是可以看到无论是PPPoA还是PPPoE,多少都有这样那样的限制,所以有一些运营商使用DHCP的方式通过BAS向用户下发TCP/IP 信息。

DHCP的连接方式非常简单粗暴,不需要PPP繁琐的验证或者添加头部的操作等,所以MTU的不需要额外的头部占用空间。

DHCP是什么? 动态主机设置协议(英语:Dynamic Host Configuration Protocol,缩写:DHCP),又称动态主机组态协定,是一个用于IP网络的网络协议,位于OSI模型的应用层,使用UDP协议工作,主要有两个用途:

  • 用于内部网或网络服务供应商自动分配IP地址给用户
  • 用于内部网管理员对所有电脑作中央管理

注意这个协议不要和HDCP 弄混了。

注意:PPPoA 不能用于 FTTH,因为 FTTH 不使用 ATM 信元。

网络运营商内部处理

通过FTTH和ADSL接入网之后,用户就与签约的运营商连接上了,这时候互联网的入口被称作POP。那么网络运营商是如何组织的?在国内毫无疑问就是三大家移联电三家三分天下,但是在国外情况不太一样,运营商之间是互相连接并且运营商是非常多的。

POP接入的方式在上面的传输过程图中基本上介绍的差不多了,这里进行总结一下,主要有四种:

  • 专线接入:指的是路由器具备通信线路端口的一般路由器。
  • 拨号连接:使用路由器为RSA,因为需要对用户拨电话进行应答,而RSA刚好有这样的功能。
  • PPPoE接入:身份认证和配置下发需要BAS负责,运营商只做转发包的操作。
  • PPPoA接入:DSLAM 通过 ATM 交换机 B与 ADSL 的运营商的 BAS 相 连, 然后再连接到运营商的路由器。

但是众多的POP要如何和运营商进行交互呢?这里就需要提到NOC的概念。

NOC: Network Operation Center,网络运行中心。NOC是网络运营商的核心,可以抽象的看作一个非常高性能的支持非常非常多用户连接的高吞吐路由器,可以看作一个超大号的接入网。

在POP接入NOC之后,NOC之间通常也有线路连接,用户的网络请求会转发到距离目的地最近的运营商,找到对应的NOC之后再进行输出。

运营商之间连接

如果接入方和目的地属于相同的网络运营商,那么POP 路由器的路由表中应该有相应的转发目标,直接转发到对应的WEB服务器所在的POP路由器即可。

但是更多情况是跨运营商之间的访问,实际上同样可以通过路由表查到,只不过路由的路径要比同一个运营商要久一些,通过路由的转发,网络包就可以送往地球的任何一个地方。

运营商之间同样需要路由表的交换,互联网内部使用 BGP 机制在运营商之间交换路由信息,路由信息的传输有三种形式,分别是对等,转接和直连,对等是直接的物理连接,但是需要两个运营商之间接一根线,转接需要把全部路由信息给对方。

转接类似使用代理,委托第三方的运营商和对方进行互连,而直连方式就很简单了,就是直接在双方搭一根专线,只有这根线的两端可以互相通信,外部运营商不可借用和看到。

小结

本部分更建议加深对鱼 传输过程图的印象,里面把整个ADSL上网通信流程描绘的非常细致,在细节上有较多的网络硬件的知识,对于个人这种学软件的人来说比较难啃,这里就当留个印象以后有机会深入的时候再学习吧。(当然几乎用不着)

整个ADSL的接入大致内容介绍完成,当然这里讨论的只是整体的部分,深入各个部分的细节内容会越发的复杂,这部分不是个人学习重点不做过多探究,感兴趣的读者可以根据步骤翻阅相关资料深入了解。

《网络是怎么样连接的》读书笔记 - FTTH

简介

FTTH指的是基于光纤的接入网技术,这部分关键是了解光纤如何使用。

FTTH是现代最为流行的接入互联网的方式,虽然不知道未来会如何改变,但是目前来看光纤接入还会流行非常长的一段时间。

FTTH是什么?

光纤到户(英语:Fiber To The Home,缩写:FTTH)是一种光纤通信的传输方法。是直接把光纤接到用户的家中(用户所需的地方)。

这种光纤通信方式及策略与FTTN、FTTC、HFC(Hybrid Fiber Coaxial)等也不同,它们都是需要依赖传统的金属电线,包括双绞线及同轴电缆等,作“最后一哩”的信息传输。

更多资料:FTTH

什么是光纤?

光纤是光导纤维的简写,是一种由玻璃或塑料制成的纤维,可作为光传导工具。传输原理是“光的全反射”。和ADSL复杂的多频段电信号不同,光信号非常简单,只需要用暗和亮表示0和1即可,具体的传输方式是通过材料的特性使用高电压发亮光和低电压发暗光,在接收端通过光敏组感应光亮变化来确定产生不同的电压,关于光纤的通信原理可以看下面的图表:

单模和多模

光纤设计最大的难点也是特点就是让光限制在一定的角度进入,由于反射会产生相位变化,如果相位不一致的光纤汇集就会出现干涉,这个现象和水波类似,如果两道水波之间互相碰撞最终结果是相互抵消。

所以光纤材料中纤芯的材质非常关键,通过光纤的直径可以划分为单模和多模两种,单模的纤芯非常细,入射角度很小的光才能进入,而多模刚好相反,它会比较粗并且入射角度更大的光也可以进入,但是单模和多模的主要区别仅是同一角度有多少相位一致的有多少可以进入。

单模和多模的区别是在传输的失真控制上,由于多模可以进入更多的光线,所以对于材料要求可以稍微低一些,但是信号失真会变强,而单模由于只传到一条光线,需要更昂贵的材料支撑,但是信号失真的概率越小。

最后光纤有一个无法避免的通病,那就是线路越长失真越大,这是任何材料都无法避免的问题。

光纤接入方式

光纤代替ADSL接入互联网的方式别称作ADSL,而接入方式主要为直连和分路的方式接入。

  1. 第一种方式是把用户端接入到最近的电话局,这种接入方式也是从ADSL上进行改良的,只不过把电信号换成了光信号,同时不需要把MAC网络包转为信元直接把以太网的包转为光信号传输即可,另外传输的时候由于是同一条光纤进行传输,为此上行的信号和下行的传输混合会通过棱镜的原理进行划分,简单来说就是是上行和下行信号采用不同波长的光,这样传输的时候即使混合也可以正常传输。
代码语言:txt复制
除了光纤替代了ADSL传输之外,整体的传输过程和ADSL大体类似。

波分复用:在一条光纤中使用不同的波长传输多个光信号。

  1. 第二种方式就是在用户附近的电线杆上安装一个分光器的东西,这种方式是目前我们比较常看到的方式,这种方式通过多个用户接入,用户端不使用光纤收发器而是通过ONU的设备替换,在数据发送到BAS总线,会通过OLT的设备接收。OLT 和 ONU 中具备通过调整信号收发时机来避免碰撞的功能,同时因为是多个用户接入一个分光器,为了防止信号错误传入其它用户泄露隐私,分光器会在不同的接入用户端添加ONU标识,最后转化为对应的以太网信号传输。

ONU是什么?

ONU就是Optical Network Unit 光网络单元。ONU具有两点作用:对OLT发送的广播进行选择性接收,若需要接收该数据要对OLT进行接收响应;对用户需要发送的以太网数据进行收集和缓存,按照被分配的发送窗口向OLT端发送该缓存数据。

在FTTx网络不同的部署ONU接入方式也有所不同,例如 FTTC(Fiber To The Curb):ONU放置在小区的中心机房;FTTB(Fiber To The Building):ONU放置在楼道的接线箱;FTTH(Fiber To The Home):ONU放置在家庭用户中。

光纤历史

最后补补光纤的历史,我们可能误以为光纤是跟随计算机的发展一起发展的,实际上早在电报时代就已经有相关的历史了。

1880年,亚历山大·贝尔Alexander Graham Bell发明了“光话机”。

1887年,英国科学家Charles Vernon Boys在实验室里拉出了第一条光纤。

1938年,美国Owens Illinois Glass公司与日本日东纺绩公司开始生产玻璃长纤维。 1951年,光物理学家Brian O’Brian提出了包层的概念。

1956年,密歇根大学的一位学生制作了第一个玻璃包层光纤,他用一个折射率低的玻璃管熔化到高折射率的玻璃棒上。

1960年,Theodore Maiman 向人们展示了第一台激光器。这燃起了人们对光通信的兴趣,激光看起来是很有前途的通信方式,可以解决传输带宽问题,很多实验室开始了实验。

1966年,英籍华裔学者高锟指出了利用光纤进行信息传输的可能性和技术途径,奠定了现代光通信——光纤通信的基础。

1970 年,美国康宁(Corning)公司就研制成功损耗20dB/km的石英光纤。 1973 年,美国贝尔(Bell)实验室取得了更大成绩,光纤损耗降低到2.5dB/km。 1976 年,日本电报电话(NTT)公司将光纤损耗降低到0.47 dB/km(波长1.2μm)。

可以看到光纤前后是有100年的历史,不像是计算机一样突然的技术爆炸产生的,从整个历史时间轴可以看到高琨实际上是主要核心,在1966年,高锟先生首次提出当玻璃纤维的衰减率低于20dB/km时,光纤通信即可成功。

因为他的这一发现是真正的将理论作用于现实转变的人,他也因为光纤直接拿了诺贝尔奖,对人类社会的发展进程影响深远。

小结

FTTH的接入方式实际上是对ADSL方式到一种改进,主要要点是使用光纤材料替代原本的电话线传输,但是需要注意光纤虽然可以使用光信号进行传输,但是最终依然需要转为电信号才能完成互联网通信。

全书总结

算是很入门的一本书了,配合大量图画和作者的文字基本对整个互联网认知上升一个层次。

如果笔记中存在描述错误或者意义模糊的地方欢迎指出。

0 人点赞