图解TCP-IP学习笔记

本文是对《图解TCP-IP》一书学习后摘录的笔记。都是网络中最基础的知识。虽然是图解,但是传图太麻烦。就不截图了。˙

TCP/IP基础知识

TCP/IP模型

  • 硬件(物理层)
  • 网络接口层(数据链路层)
  • 互联网层(网络层)
    • IP:跨越网络发送数据包,使整个互联网都能收到数据的协议。
    • ICMP:IP数据包发送途中出现异常无法发送到目标地址时,给发送端一个异常通知。ICMP就是为这一功能定制的
    • ARP:从分组数据包解析出物理地址(MAC地址)的一种协议。
  • 传输层
    • TCP:面向连接的传输层协议。可以保证两端通信主机间的通信可达。
    • UDP:面向无连接的传输层协议。
  • 应用层(会话层以上的分层)
    • WWW
    • 电子邮件(E-Mail)
    • 文件传输(FTP)
    • 远程登录(TELNET,SSH)
    • 网络管理(SNMP)

物理层协议

物理层是五层模型中的最底层,物理层为计算机之间的数据通信提供了传输媒体和互连设备,为数据传输提供了可靠的环境,媒体包括电缆、光纤、无线信道等,互连设备指是计算机和调制解调器之间的互连设备,如各种插头、插座等。该层的作用是透明的传输比特流(即二进制流),为数据链路层提供一个传输原始比特流的物理连接

数据链路层

数据链路层是模型中的第2层,该层对接受到物理层传输过来的比特流进行分组,一组电信号构成的数据包,就叫做”帧”,数据链链路层就是来传输以”帧”(frame)为单位的数据包,把数据传递给上一层(网络层),帧数据由两部分组成:帧头和帧数据,帧头包括接受方物理地址(就是下一级的网卡地址和其他的网络信息,帧数据就是要传输的数据体。数据帧的最长为1500字节,如果数据很长,就必须分割成多个帧进行发送。

网络层

该层通过寻址(寻址地址)来建立两个节点之间的连接,大家都知道我们的电脑连接上网络后都有一个IP地址,我们可以通过IP地址来确定不同的计算机是否在同一个子网路。如果我们的电脑连接上网络后就有两种地址:物理地址和网络地址(IP地址),网络上的计算机要通信,必须要知道通信的计算机“在哪里”, 首先通过网络地址来判断是否处于同一个子网络,然后再对物理地址(MAC)地址进行处理,从而准确确定要通信计算机的位置。

在网络层中有我们熟悉的IP协议(即规定网络地址的协议),目前广泛采用的是IPv4,这个版本规定,网络地址由32位二进制位组成。我们可以自己配置IP地址也可以自动获得的方式得到IP地址,IP地址分成两部分,前24位代表网络,后8位代表主机号, 如192.168.254.1和192.168.254.2就处于同一个子网络里,因为这两个IP地址的前24位相同。

帧数据区含有一个数据体。为确保计算机能够解释数据帧中的数据,这两台计算机使用一种公用的通讯协议。互联网使用的通讯协议简称IP,即互联网协议。IP数据包也包括两部分:头(Head)和数据(Data),IP数据包(Packet)放进数据帧中的数据部分进行传输

Mac地址在帧头中,IP地址在帧数据中的IP数据包头中,这样交换机可以快速读取Mac地址进行转发,而不需要像路由器一样需要解包将IP地址取出,才能进行转发,影响效率。

传输层

通过MAC和IP地址,我们可以找到互联网上任意两台主机来建立通信。然而这里有一个问题,找到主机后,主机上有很多程序都需要用到网络,比如说你在一边听歌和好用QQ聊天, 当网络上发送来一个数据包时, 是怎么知道它是表示聊天的内容还是歌曲的内容的, 这时候就需要一个参数来表示这个数据包是发送给那个程序(进程)来使用的,这个参数我们就叫做端口号,主机上用端口号来标识不同的程序(进程),端口是0到65535之间的一个整数,0到1023的端口被系统占用,用户只能选择大于1023的端口。

传输层的功能就是建立端口到端口的通信网络层就是建立主机与主机的通信,这样如果我们确定了主机和端口,这样就可以实现程序之间的通信了。我们所说的Socket编程就是通过代码来实现传输层之间的通信。因为初始化Socket类对象要指定IP地址和端口号。

在传输层有两个非常重要的协议:UDP 协议和TCP协议

采用UDP协议话传输的就是UDP数据段,同样UDP数据段也由头和数据两部分组成,头部分主要标识了发送端口和接受端口,数据部分就是具体的内容信息。同样UDP数据段(segment)是放入IP数据包中的”数据”部分,IP数据包再放入数据帧中在网络上传输。

由于UDP协议的可靠性差(数据发送后无法确定对方是否收到),所以又定义了一个可靠性高的协议——TCP协议,TCP协议采取了握手的方式要确保对方收到了数据。

TCP 协议的三次握手主要的目的是为了确定客户端要和服务器建立链接,以防服务器一直等待造成的性能损失。客户端先发一个同步信息告诉服务器要建立链接,服务器返回一个确认信息,客户端接收到之后再返回一个确认信息。如果不这样做,可能因为网络延迟,客户端的信息再一段时候后才被服务器接收,服务器等待客户端数据,但是由于过了一段时间,客户端可能已经停止了请求操作,这就导致了服务器性能的浪费。

应用层

应用层是模型中的最顶层,是用户与网络的接口,该层通过应用程序来完成网络用户的应用需求。该层的数据放在TCP数据包的数据部分,该层定义了一个很重要的协议——Http协议,我们一般的Web开发都是基于应用层的开发。

数据包如何在网络中传输

当我们向目标站点发送数据包时(比如 ping 一个地址),就生成了一个包含 ICMP 协议域的数据包,我们暂且称之为“小德”。

“小德”已经将ICMP协议打包到数据段里了,可是还不能发送,因为一个数据要想向外面传送,还得经过“有关部门”的批准——IP协议。IP要将你的“写信人地址”和“收信人地址”写到数据段上面,即:将数据的源IP地址和目的IP地址分别打包在“小德”的头部和尾部,这样一来,大家才知道你的数据是要送到哪里。

准备工作还没有完。接下来还有部门要审核——ARP。ARP主要负责把IP地址对应到硬件地址。直接说吧,都怪二层交换机太“傻”,不能根据IP地址直接找到相应的计算机,只能根据硬件地址来找。于是,主机或者三层交换机(不是指交换机啊,ARP 是工作在网络层的,不是数据链路层啊)就经常保留一张IP地址与硬件地址的对应表以便其查找目的地。而ARP就是用来生成这张表的。比如:当“小德”被送到ARP手里之后,ARP就要在表里面查找,看看“小德”的IP地址与交换机的哪个端口对应,然后转发过去。如果没找到,则发一个广播给所有其他的交换机端口,问这是谁的IP地址,如果有人回答,就转发给它。如果没有,就准备由二层交换机转发到路由器(这之前都是在主机里查询 ARP 表),走出局域网了。(其实就是我们要发送信息,我们只知道要发给的主机的ip地址,但是不可能知道主机的MAC地址。但是交换机要通过MAC地址转发,所以就有了这么一个ARP表,放在主机或者三层交换机里

经过一番折腾,“小德”终于要走出这个倒霉的局域网了。可在此之前,它们还没忘给“小德”屁股后面盖个“戳”,说是什么CRC校验值,怕“小德”在旅行途中缺胳膊少腿,还得麻烦它们重新发送。。。。。我靠~~~~注:很多人弄不清FCS和CRC。所谓的CRC是一种校验方法,用来确保数据在传输过程中不会丢包,损坏等等,FCS是数据包(准确的说是frame)里的一个区域,用来存放CRC的计算结果的。到了目的地之后,目的计算机要检查FCS里的CRC值,如果与原来的相同,则说明数据在途中没有损坏。

在走出去之前,那些家伙最后折磨了一次“小德”——把小德身上众多的0和1,弄成了什么“高电压”“低电压”,在双绞线上传送了出去。晕~~出趟门就这么麻烦吗?

坐着双绞线旅游,爽!可当看到很多人坐着同轴电缆,还有坐光纤的时候,小德又感觉不是那么爽了。就在这时,来到了旅途的中转站——路由器。这地方可是高级场所,人家直接查看IP地址!剩下的一概不管,交给下面的人去做。够牛吧?路由器的内部也有一张表,叫做路由表,里面标识着哪一个网络的IP对应着路由器的哪一个端口。这个表也不是天生就有的,而是靠路由器之间互相“学习”之后生成的,当然也可以由管理员手工设定。这个“学习”的过程是依靠路由协议来完成的,比如RIP,EIGRP,OSPF等等。

当路由器查看了“小德”的IP地址以后,根据路由表知道了小德要去的网络,接着就把小德转到了相应的端口了。至此,路由器的主要工作完成,下面又是打包,封装成frame,转换成电压信号等一系列“折腾”的活,就由数据链路层和物理层的模块去干吧。

小德从路由器的出口出来,便来到了目的地—-电脑B—-所属的网络的默认网关。默认网关可以是路由器的一个端口,也可以是局域网里的各种服务器。不管怎样,下面的过程还是一样的:到三层交换机里的ARP表查询“小德”的IP地址,看看属于哪个局域网段或端口,然后就转发到B了。

进了B的网卡之后,还要层层“剥皮”,基本上和从A出来的程序是一样的——电脑B先校验一下CRC值,看看数据是否完整;然后检查一下frame的封装,看到是IP协议之后,就把“小德”交给IP“部门”了;IP协议一看目的地址,正确,再看看应用协议,是ICMP。于是知道了该怎么做了——产生一个回应数据包,(可以命名为“回应小德”),并准备以同样的顺序向远端的A发送。。至于刚刚收到的那个数据包就丢弃了。

一个出口多个入口的是交换机,每个入口都对应着一个终端,是网络传输开始的部分,通过 MAC 地址转发

多个出口多个入口的是路由器,会解析 IP 头,找到适合的出口将数据传输出去。

家用路由器=交换机+NAT。如果用交换机相当于每台家用设备需要一个 IP,但是如果使用家用路由器,那么通过 NAT 只需要给一个 IP 即可。

IP协议

IP网络协议

网络层的下一层——数据链路层主要作用是在互连同一种数据链路节点之间进行包传递(局域网)。而一旦跨越多种数据链路,就需要借助网络层。网络层可以跨越不同数据链路,即使在不同数据链路上也能实现两端节点之间的数据包传输。

配有IP的地址的设备称为主机。和路由器不同,路由器即配有IP地址,又具有路由控制能力。节点是主机和路由器的统称。

网络层与数据链路层关系:数据链路层提供直连两个设备的能力。与之相比,网络层的IP则负责在没有直连的两个网络之间进行通信传输。比如旅行,数据链路相当于各个中转的火车票,而IP相当于是个旅行表。没有车票,无法达到目的地,没有旅行表,则不知道做什么车。

IP基础知识

IP大致分为三大模块,IP寻址,路由,IP分包和组包。

为识别通信对端,必须有一个类似于地址的识别码进行标识。MAC地址正是用来标识同一个链路中不同计算机的一种识别码IP也有这种地址信息,用于在连接到网络中的所有主机中识别出进行通信的目标地址。因此,TCP/IP中所有主机或路由必须设定自己的IP地址。

路由控制将分组数据发送到最终目标地址。为了将数据发给目标主机,所有主机都维护着一张路由控制表。该表记录IP数据在下一步应该发给哪个路由器。IP包将根据这个路由表在各个数据链路上传输。

IP地址的基础知识

IP地址由网络标识和主机标识组成。网络标识必须保证相互连接的每个段的地址不重复。而相同段内相连的主机必须有相同的网络地址。IP地址的“主机标识”则不允许在同一个网段内重复出现。

广播地址用于在同一个链路中互相连接的主机间发送数据。将主机地址部分全部设置为1,就成了广播地址。

多播用于将包发送给特定组内的所有主机。凡是以1110开头的都是多播地址,剩下的28为是多播的组编号。

网络标识相同的计算机必须属于同一链路,但如A类B类将产生大量浪费的地址,因为不可能有那么多主机连接在一个链路上。现在,可以通过一个叫做”子网掩码“的识别码通过子网网络地址细分出比ABC更小粒度的网络。
子网掩码也是32位,对应网络地址的部分为1,对应主机地址的部分对应为0。比如A类网络的子网掩码就是255.0.0.0(前8位全是1),B类网络的子网掩码就是255.255.0.0(前16位全是1)。

由于互联网的普及,IP地址不足问题严重。于是出现私有网络的IP地址。它的地址范围:A类,10.0.0.0-10.2555.255.255;B类,172.16.0.0-172.31.255.255;C类,192.168.0.0-192.168.255.255。包含在这个范围内的IP都属于私有IP,在此之外的IP称为全局IP。内部每个终端使用私有IP,而在路由器(宽带路由器)或必要服务器上设置全局IP。当配有私有IP的主机联网时,使用NAT进行通信。

对于FTTH和ADSL服务,网络供应商直接给用户分配全局IP地址,并且每次用户重连,该IP地址都可能发生变化。这里的IP地址由供应商维护,不需要用户自己申请全局IP。

路由控制

仅仅有IP地址不足以实现将数据包发送到对端目标地址,在数据发送过程中还需要指明路由器或主机的信息,以便真正发往目标地址。保存这种信息的就是路由控制表

路由控制表记录着网络地址和下一步应该发送至路由器的地址。发送IP包时,先确定IP包首部中的目标地址,再从路由控制表中找到与该地址具有相同网络地址的记录,根据该记录将IP包转发给相应的下一个路由器。

路由算法

距离向量算法

采用Bellman-Ford算法,保存网络中的所有路由器及网络的拓扑图。比较费时费性能。

链路状态算法

采用Dijkstra 算法

当一个路由器启动的时候,向邻居发送消息,邻居立刻回复,从而计算和邻居的距离。然后将自己和邻居的链路状态广播出去,发送到整个网络的所有路由器。因此,每一个路由器都可以在本地构建一个完整的图,然后使用 Dijkstra 算法,找到两点的最短路径。

IP协议相关

ICMP

ICMP 主要用来确认 IP 包是否成功到达目标地址。使用 UDP 协议。一般所说的 ping 一个 IP 就是使用 ICMP 协议。

NAT

NAT 用于在本地网络中使用私有地址,在连接互联网时使用全局 IP 地址。NAT 主要解决的是 IPv4 IP 地址枯竭的问题。

NAT 内部的机器通过 NAT 路由器将内部 IP 转化为外部 IP,与外部机器通信。

NAT 内部维护了一个 NAT 转化表。将内部不同的机器映射为不同的端口号。比如内部 10.0.0.10 映射为外部IP 202.244.174.37:1025,将 10.0.0.11映射为外部 IP 202.244.174.37:1026

其实就是虽然只有一个外网IP,但是可以通过端口号拓展很多的内部机器。

对于第四层是TCP或UDP的数据包,NAT通过更改源端口号,来实现多对少的映射。

对于ICMP包,NAT通过更改ICMP的ID,来实现多对少的映射。

(NAT违反了基本的网络分层结构模型的设计原则。因为在传统的网络分层结构模型中,第N层是不能修改第N+1层的报头内容的。NAT破坏了这种各层独立的原则。)

DNS

DNS帮助用户在互联网上寻找路径。在互联网上的每一个计算机都拥有一个唯一的地址,称作“IP地址”(即互联网协议地址)。由于IP地址(为一串数字)不方便记忆,DNS允许用户使用一串常见的字母(即“域名”)取代。在每次 TCP/IP 通信前,都会先通过 UDP 协议,向 DNS 服务器请求 IP 地址。

其实dns系统是一个典型的树状架构,我们设置的dns服务器其实应该叫dns缓存查询服务器,它是为了减轻互联网上dns查询的负载所设计的。如果你的请求没有命中缓存,那么这个缓存服务器就会自己进行一次标准查询,然后再把结果缓存起来,简单来说就是从根服务器开始一级一级的问。我们以前经常谈到根服务器的重要性其实就体现在这里了,它保留了对所有域名的起始解释权。

上面讲到根服务器拥有一切域名的起始解释权,但是如果你去问根服务器它是不会直接告诉你最终答案的。因为如果它要存储所有的记录,那它也太累了,这个负载和开销是惊人的。那它会告诉你什么呢?它会告诉你应该去问谁,也就是它授权下一级服务器来解答你的问题。所以可见,dns系统本身是一个分布式的网络。

DNS 劫持

 DNS劫持就是通过劫持了DNS服务器,通过某些手段取得某域名的解析记录控制权,进而修改此域名的解析结果,导致对该域名的访问由原IP地址转入到修改后的指定IP,其结果就是对特定的网址不能访问或访问的是假网址,从而实现窃取资料或者破坏原有正常服务的目的。DNS劫持通过篡改DNS服务器上的数据返回给用户一个错误的查询结果来实现的。

对于DNS劫持,可以采用使用国外免费公用的DNS服务器解决。例如OpenDNS(208.67.222.222)或GoogleDNS(8.8.8.8)。

DNS 污染

DNS污染是一种让一般用户由于得到虚假目标主机IP而不能与其通信的方法,是一种DNS缓存投毒攻击(DNS cache poisoning)。其工作方式是:由于通常的DNS查询没有任何认证机制,而且DNS查询通常基于的UDP是无连接不可靠的协议,因此DNS的查询非常容易被篡改,通过对UDP端口53上的DNS查询进行入侵检测,一经发现与关键词相匹配的请求则立即伪装成目标域名的解析服务器(NS,Name Server)给查询者返回虚假结果。

对于DNS污染,可以说,个人用户很难单单靠设置解决,通常可以使用VPN或者域名远程解析的方法解决,但这大多需要购买付费的VPN或SSH等,也可以通过修改Hosts的方法,手动设置域名正确的IP地址。

HTTPDNS

HTTPNDS 其实就是,不走传统的 DNS 解析,而是自己搭建基于 HTTP 协议的 DNS 服务器集群,分布在多个地点和多个运营商。当客户端需要 DNS 解析的时候,直接通过 HTTP 协议进行请求这个服务器集群,得到就近的地址。

其实就是就近找 DNS

总结

DNS劫持就是指用户访问一个被标记的地址时,DNS服务器故意将此地址指向一个错误的IP地址的行为。

DNS污染,指的是用户访问一个地址,国内的服务器(非DNS)监控到用户访问的已经被标记地址时,服务器伪装成DNS服务器向用户发回错误的地址的行为。

修改DNS

可以手动修改本机的 DNS,也可以不修改使用路由器的 DNS,路由器可以手动修改 DNS,也可以不修改使用运营商的 DNS。

附: GFW 的实现

GFW 就是所说的墙,有三种方式屏蔽网络上传播的内容:

内容审查

GFW的内容审查针对HTTP传输协议的默认端口的80端口,HTTP传播的内容是明文的内容,没有经过加密,GFW是一个IDS[Intrusion detection system(入侵检测系统)],GFW有一个敏感字名单,若在中国大陆访问境外的主机的HTTP的数据流里发现敏感字眼,就在两台主机间伪造一个”reset”信号,导致双方主机以为对方中止了请求。

DNS劫持和污染

DNS劫持:通过网络服务提供商(Internet ServiceProvider/ISP)提供的DNS服务器进行DNS欺骗,当人们访问某个网站时,需要要把域名转换为一个IP地址,DNS服务器负责将域名转换为IP地址,中国大陆的ISP接受通信管理局的屏蔽网站的指令后在DNS服务器里加入某些特定域名的虚假A记录,当使用此DNS服务器的网络用户访问此特定网站时,DNS服务便给出假的IP地址,导致访问网站失败,甚至返回ISP运营商提供的出错页面和广告页面。

DNS污染:GFW在DNS查询使用的UDP53端口上根据黑名单进行过滤,遇到通往国外的使用UDP的53端口进行查询的DNS请求,就返回一个虚假的IP地址(即使用国外的服务器查询就会返回一个虚假的地址)。

屏蔽IP

有些人改了 hosts,直接将谷歌的域名映射到 ip,但是GFW可以通过路由器(router)来控制的,在通往国外的最后一个网关上加上一条伪造的路由规则,导致通往某些被屏蔽的网站的所有IP数据包无法到达。路由器的正常工作方式是学习别的路由器广播的路由规则,遇到符合已知的IP转发规则的数据包,则按已经规则发送,遇到未知规则IP的数据,则转发到上一级网关。GFW的路由器按黑名单(blacklist)来转发特定的IP数据包,则可屏蔽特定的网站的IP,此IP黑名单不是固定的,会更新。

TCP与UDP

TCP

概述

tcp采取全双工(full-duplex)传输,也就是传输过程中,同一连接可以传输双向的数据流,发送方可以传给接收方,接收方也可以传给发送方。

tcp是面向连接的协议。其实,网络上的传输是没有连接的,包括TCP也是一样的。而TCP所谓的“连接”,其实只不过是在通讯的双方维护一个“连接状态”,让它看上去好像有连接一样。所以,TCP的状态变换是非常重要的。

TCP 发送信息过程

连接过程
  1. client 发送一个同步消息 SYN ,同时发送随机 seq 为 x,告诉server 发送的包序号从 x 开始。
  2. server 收到同步消息后,也返回一个 SYN 信号,同时返回一个 ACK 信号为 x+1,表示知道了你的序号,还返回了 server 的随机 seq 为 y,告诉 client,server 端序号从 y 开始。
  3. client 收到后,返回一个 ACK 为 y+1,表示 client 知道 server 的开始序号了。
断开连接过程
  1. client 发送一个断连消息 FIN ,以及随机 seq
  2. server 收到同步消息后,返回一个 ACK 信号
  3. 之后,在 server 端决定的任意时刻,发起一个断连信号 FIN,以及随机 seq
  4. client 收到后,返回一个 ACK

最后要注意的是,客户端需要在收到服务端的 FIN 并且发送 ACK 之后要等两个时间窗再关。因为客户端发送的 ACK 可能没有到达服务端。服务端会不停的发送 FIN,所以要等待一段时间,确认服务端已经关闭了,客户端再关闭

TCP 如何实现可靠传输

  1. 确认和重传
  2. 数据校验
  3. 数据合理分片与排序
  4. 流量控制
  5. 拥塞控制

TCP 确认与重传机制

一种方式是超时重传,就是对每一个没有 ACK 的包都设置一个定时器,超过一定时间后尝试重传。超时重传的周期不宜过短也不宜过长,过短别人可能真的没有接收到,过长又会阻塞信息传输。一般的策略是每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送。

针对超时重传周期可能过长的问题,采取快速重传的机制。当接收方收到一个序号大于下一个所期望的报文段时,就检测到了数据流中的一个间格,接收方还是发送期望报文段之前的报文的 ACK。当客户端连续收到三个这样的 ACK 时,就在定时器过期之前,重传丢失的报文段。

快速重传解决了重传周期长的问题,但是没解决重传一个还是重传多个的问题。因此还出现了选择确认机制,TCP 头里加一个 SACK 的东西,可以将缓存的地图发送给发送方。这样一下子就能知道丢失了什么。

TCP 流量控制

本质上就是在发送方维持一个滑动窗,窗的大小由接收端控制。

TCP 拥塞控制

滑动窗口 rwnd 是怕发送方把接收方缓存塞满,而拥塞窗口是怕把网络塞满。

TCP 使用滑动窗的方式发送数据,收发主机之间不再以数据段为单位发送确认应答。这个时候可能产生拥堵。TCP 为了防止这样的问题,一般采用如下做法:

慢启动:主要做法就是试探,首先在一个单位时间里发送一个报文。如果收到了确认回执,那么翻倍发送,直到拥塞,数据丢失,这一阶段报文的数量是以指数级增长。

拥塞避免:慢启动的时候是指数增长的,但是增长是有个门限ssthresh的,到达门限后进入拥塞避免阶段。拥塞避免状态,每次增长一个报文。

快速恢复:当出现丢包,并且实施了快速重传的时候,就表明网路还是较为畅通的,此时此时就不会直接进入慢启动状态,而是将传输的报文数量减半,然后继续拥塞避免。

只有在快速重传的时候才会进入快速恢复。如果是超时重传,那么就要重新进行又一轮的慢启动。

三次握手

为什么要三次握手不是两次?

主要是为了节约 server 端的 socket 资源。如果两次握手,服务端在第二次握手后维护了一个连接。但是客户端没有收到服务端的ACK,这时候客户端以为服务端没有建立连接就会重新发送 SYN 请求建立连接。服务端前一个建立的连接就是死连接了。一个进程打开的socket是有限度的, 维护这些死连接非常耗费资源。

为什么是三次握手不是四次?

其实本身,client 发送同步信号 SYN 以及 seq,server 回复 ACK,随后 server 发送同步信号 SYN 以及 seq,client 回复 ACK 是四次。但是 server 发送 seqACK 可以合并为一次,因此就只需要三次了。

四次挥手

本质上和握手时client 通知,server 回复。server 通知,client 回复一样是四次。但是在客户端请求结束的时候,服务端可能在发数据,所以不能把 ACK 和 FIN 像握手的时候一起发送。所以一般情况下要四次。但是如果当时服务端没有再发送数据,那么也可以三次挥手。

四次挥手能否变成三次挥手?

可以,如果Server在收到Client的FIN包后,在也没数据需要发送给Client了,那么对Client的ACK包和Server自己的FIN包就可以合并成为一个包发送过去,这样四次挥手就可以变成三次了。

UDP

UDP 如何保证可靠性

为什么要在 UDP 之上做可靠保证,究其原因就是在保证通信的时延和质量的条件下尽量降低成本。

那么在 UDP 之上怎么实现可靠呢?答案就是重传。

就是把 TCP 的这几个可靠性机制能搬多少搬多少。

几张表

MAC地址转发表

说到MAC地址表,就不得不说一下交换机的工作原理了,因为交换机是根据MAC地址表转发数据帧的。在交换机中有一张记录着局域网主机MAC地址与交换机接口的对应关系的表,交换机就是根据这张表负责将数据帧传输到指定的主机上的。

交换机在接收到数据帧以后,首先、会记录数据帧中的源MAC地址和对应的接口到MAC表中,接着、会检查自己的MAC表中是否有数据帧中目标MAC地址的信息,如果有则会根据MAC表中记录的对应接口将数据帧发送出去(也就是单播),如果没有,则会将该数据帧从非接受接口发送出去(也就是广播)。

上面说的交换机指的是二层交换机

这张表存在于交换机中,记录的是 MAC地址 -> 端口的映射

ARP缓存表

上面我们讲解了交换机的工作原理,知道交换机是通过MAC地址通信的,但是我们是如何获得目标主机的MAC地址呢?这时我们就需要使用ARP协议了,在每台主机中都有一张ARP表,它记录着主机的IP地址和MAC地址的对应关系。ARP协议是工作在网络层的协议,它负责将IP地址解析为MAC地址。

知道下一跳的 IP,但是不知道下一跳的 MAC 地址是无法传输的。所以当知道 IP 但不知道 MAC 地址的时候,就要通过 ARP 发送一个广播包,问这个 IP 是谁的?MAC 地址是多少?

上面指的是局域网中的数据传递。除了主机中,三层交换机或者路由中也是有 ARP 表的,数据最终转发依靠的都是ARP表,他是数据转发最基础的依据,ARP直接将硬件地址和网络地址相互映射

这张表记录的是 IP -> MAC 地址的映射。

路由表

路由器负责不同网络之间的通信,它是当今网络中的重要设备,可以说没有路由器就没有当今的互联网。在路由器中也有一张表,这张表叫路由表,记录着到不同网段的信息。

路由器是工作在网络层的,在网络层可以识别逻辑地址。当路由器的某个接口收到一个包时,路由器会读取包中相应的目标的逻辑地址的网络部分,然后在路由表中进行查找。如果在路由表中找到目标地址的路由条目,则指定下一跳 ip,然后把包转发到路由器的相应接口,如果在路由表中没有找到目标地址的路由条目,那么,如果路由配置默认路由,就按照默认路由的配置转发到路由器的相应接口;如果没有配置默认路由,则将该包丢弃,并返回不可到达的信息。这就是数据路由的过程。

这张表记录的是 目标IP -> 下一跳路由 IP 的映射

三张表是有一个层次关系的。每次 IP 的跳转都要结合三张表,从目标 IP 到 目标 MAC 所在端口的转换。

问题

  • 为什么不把MAC地址和IP地址统一成一个地址而用两个地址?
  • 什么是中继器/网桥/路由器/三层交换机/二层交换机/网关?
  • TCP/IP 五层模型各指什么?各自的作用是什么?
  • IP/ARP/TCP/UDP/HTTP/FTP 这些协议分别处于哪一层?作用是什么?
  • 什么是帧?IP 地址和 MAC 地址分别放在帧的哪一部分,这样有什么好处?
  • 为什么 TCP 协议要进行三次握手,四次挥手?
  • 简述数据包如何在网络中传输?
  • ARP缓存表,MAC地址表,路由表的作用分别是什么?
  • 什么是DNS?基本原理是什么?为什么说它是分布式的网络?
  • 什么是DNS劫持?什么是DNS污染?