【网络】基础复习

来源:互联网 发布:.net cms 源码 编辑:程序博客网 时间:2024/06/06 15:37

复习的起点:网络协议的体系结构;

OSI七层协议和TCP/IP四层协议


OSI七层协议

从上往下:应用层,表示层,会话层,传输层,网络层,数据链路层,物理层;

OSI七层协议是用来学习的协议模型,在实际使用中使用的基本都是TCP/IP四层协议;

前三层只学习应用层:即用户使用,如http,ftp等协议;
传输层: TCP、UDP 都是传输层的协议,不过两者有很大的区别,后面细细复习;
网络层:负责不同主机的通信服务,使用的是IP协议;
数据链路层:数据总是在一段一段的链路上传输,所以规定了协议,其中在OSI七层协议中ARP协议属于数据链路层;
物理层:字面上的物理,就是传统意义上的物理设备的链接;

而实际通信的过程中,数据是通过贯穿协议栈的方式进行数据的封装和发送的,这个封包和解包的具体过程在下面复习;


TCP/IP四层协议

从上往下:应用层,传输层,网际层,网络接口层;

TCP/IP四层协议将OSI七层协议的上三层和下两层都进行了合并,就成为了现在的四层协议,其中OSI的应用层,表示层和会话层合并为了TCP/IP的应用层,OSI的数据链路层和物理层合并为TCP/IP的网络接口层;

在复习OSI七层协议的时候,我们说到数据的传输过程是贯穿协议栈的,在发送和接受方不断的封包和解包的; 核心的数据一直被包裹在其中,只不过在路过每一层的时候都要被打上那一层的标签,所谓通关文牒,也就是每一层的帧格式,下面就TCP/IP四层协议每一层的帧格式来复习;(我以为这个大概了解就好了,就在我面腾讯的时候,居然让我把每一层的格式说出来,更有甚者,让我直接说出TCP的报头长度,可见现在找工作的不容易,面试官使出浑身解数啊,至于能不能记下,就看各位共同奋斗的同志的造化了);

以太网帧格式:

源MAC地址,目的MAC地址,类型,数据,帧校验

在网络层,IP协议是最主要的协议,配套的还有ARP, ICMP, IGMP 协议;

IP数据报格式:
这里写图片描述

版本:占4位,指IP协议的版本,IPV4或者IPV6;
首部长度:占四位,5~15之间,即首部长度最小为20个字节,最大为60个字节,当首部长度不是4的倍数的时候就用到了最后的填充字段;
服务类型:占8位,一般情况不使用;
总长度: 指首部和数据的总长度,占16位;

当数据超过1500字节时需要进行分片,即接下来字段的意义;

标识:占16位,标识其中一个分片;
标志:占3位,只有两位起作用,分别表示是否可以被分片和是否是最后一个分片;
片偏移:占13位,某片在原分组中的位置;

生存时间(TTL):占8位,即数据报的寿命,在转发过程中的跳数;
协议: 占8位, 协议字段指出此数据报携带的数据是使用何种协议,以便使目的主机知道把数据上交给哪个处理过程;
首部校验和:占16位,只检验数据包的首部;
源IP地址和目的IP地址:都占32位;

在网络层和IP协议配合使用的协议ARP协议:地址解析协议,在OSI七层协议中,这个协议被认为是数据链路层的协议,而在TCP/IP四层协议中属于网络层协议;

地址解析协议的作用是通过目的主机的IP地址得到目的主机的MAC地址,使得MAC帧可以顺利打包;

ARP数据帧格式如下:
这里写图片描述

ARP的执行过程,当A主机向B主机发送消息的时候,A主机只知道B主机的ip地址,不知道物理地址怎么办? ARP有个高速缓存,用来存放最近通信过的目的主机的MAC和IP的映射表,先来查这张表,如果没有,那就带着B主机的IP地址在局域网内进行广播,这是谁的IP地址啊? 把你的MAC地址给我回过来,此时如果局域网内存在这个IP地址的主机,就会回应一个ARP响应报文,带着自己的MAC地址,虽然ARP请求报文是广播的,但是响应报文是单播的;

配合IP协议的还有ICMP协议,这个协议其实也是出于夹层的协议,在不同的书里可能归在不同层,在这里,我们默认在网络层;

ICMP帧格式:

这里写图片描述

ICMP : 网络控制报文协议;

具体细节不去学习了,只复习一下ICMP的一个实际应用例子:ping命令;

PING是应用层直接使用网络层ICMP协议的一个例子,直接跳过了传输层;

还有traceroute也是用了ICMP的差错报告报文;

传输层:TCP和UDP

传输层提供了两种截然不同风格的传输协议,可以根据不同的需求选择合适的协议;

UDP:不可靠的传输协议,面向无连接的服务,尽最大可能的交付数据报;

UDP的报头格式:
这里写图片描述

下面是UDP的特点:

  1. udp的数据报的报头固定长度8个字节
  2. udp是无连接的,即发送数据之前不需要进行链接
  3. udp使用最大努力交付,说白点就是不保证数据完整和到达
  4. udp是面向报文的,即一次交付一个完整的报文
  5. udp没有拥塞控制,即网络拥塞也不会影响源主机的发送效率
  6. udp支持一对多,多对多的交互式通信

UDP的应用场景,只要面试中问到UDP那是必须问应用场景的;

既然是不可靠的传输,那么对数据的完整性要求不高的场景可以使用UDP进行传输,例如qq语言和qq视频的传输;

较短的数据报使用UDP进行传输,例如qq和微信的消息发送,这也是为什么会在网络差的时候会出现发送失败和限制发送长度的原因;

发送的数据太长的话,在IP层会被切片,影响IP层效率,但是如果数据太短的话,IP数据报头过大,也影响IP层效率;

TCP:可靠的,面向连接,字节流的传输协议;

TCP的报头格式:
这里写图片描述

TCP报头固定的20个字节分别是:

源端口地址和目的端口地址:各占32位;
序号和确认号:各占32位,是保证可靠传输的基础;
数据偏移:占4位,指出报文段数据的起始处距离TCP报文段的起始处有多远;
6位控制位:标志报文属性;
紧急指针:数据的优先,需要第一时间被交付,于是接收方就把紧急数据放在本段报文的最前方;
窗口大小:拥塞控制;

下面是TCP的特点:

  1. tcp是面向连接的传输,即发送数据前需要建立链接,建立链接的过程被称为三次握手,而取消链接的过程成为四次挥手,面试的热点问题,这个我专门总结了一篇博客:http://blog.csdn.net/bitboss/article/details/62423403
  2. 每一条tcp链接只能有两个端点,即点对点的传输;
  3. tcp提供可靠的交付服务,通过TCP传输的数据,无差错,不丢失,不重复,并且按序到达;
  4. tcp提供全双工通信
  5. 面向字节流:即交付给上层的可能不是一次完整的数据;

既然TCP提供的是可靠的传输,那么可靠的传输到底是如何实现的,包含哪些方面?

  1. 差错处理(超时重传)
  2. 有序接受
  3. seq/ack确认机制
  4. 拥塞控制

除去前面给的重要的三次握手四次挥手的链接,下面重点说的TCP保证可靠性传输主要依赖的四种定时器和拥塞控制;

下面又是一个面试的热点问题,第一次听到的时候还是懵逼的,那就是如何实现一个可靠的UDP传输?

UDP如何实现可靠传输

由于在传输层UDP已经是不可靠的连接,那就要在应用层自己实现一些保障可靠传输的机制

简单来讲,要使用UDP来构建可靠的面向连接的数据传输,就要实现类似于TCP协议的

超时重传(定时器)

有序接受 (添加包序号)

应答确认 (Seq/Ack应答机制)

滑动窗口流量控制等机制 (滑动窗口协议)

等于说要在传输层的上一层(或者直接在应用层)实现TCP协议的可靠数据传输机制,比如使用UDP数据包+序列号,UDP数据包+时间戳等方法。

目前已经有一些实现UDP可靠传输的机制,比如

UDT(UDP-based Data Transfer Protocol)
基于UDP的数据传输协议(UDP-based Data Transfer Protocol,简称UDT)是一种互联网数据传输协议。UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。 顾名思义,UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。 由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。

四种定时器:

TCP使用四种定时器(Timer,也称为“计时器”):
重传计时器:Retransmission Timer
坚持计时器:Persistent Timer
保活计时器:Keeplive Timer
时间等待计时器:Time_Wait Timer。

(1)重传计时器:Retransmission Timer

重传定时器:为了控制丢失的报文段或丢弃的报文段,也就是对报文段确认的等待时间。当TCP发送报文段时,就创建这个特定报文段的重传计时器,可能发生两种情况:若在计时器超时之前收到对报文段的确认,则撤销计时器;若在收到对特定报文段的确认之前计时器超时,则重传该报文,并把计时器复位;重传时间=2*RTT;RTT的值应该动态计算。常用的公式是:RTT=previous RTT*i + (1-i)*current RTT。i的值通常取90%,即新的RTT是以前的RTT值的90%加上当前RTT值的10%.Karn算法:对重传报文,在计算新的RTT时,不考虑重传报文的RTT。因为无法推理出:发送端所收到的确认是对上一次报文段的确认还是对重传报文段的确认。干脆不计入。

(2)坚持计时器:persistent timer

专门为对付零窗口通知而设立的。当发送端收到零窗口的确认时,就启动坚持计时器,当坚持计时器截止期到时,发送端TCP就发送一个特殊的报文段,叫探测报文段,这个报文段只有一个字节的数据。探测报文段有序号,但序号永远不需要确认,甚至在计算对其他部分数据的确认时这个序号也被忽略。探测报文段提醒接收端TCP,确认已丢失,必须重传。坚持计时器的截止期设置为重传时间的值,但若没有收到从接收端来的响应,则发送另一个探测报文段,并将坚持计时器的值加倍和并复位,发送端继续发送探测报文段,将坚持计时器的值加倍和复位,知道这个值增大到阈值为止(通常为60秒)。之后,发送端每隔60s就发送一个报文段,直到窗口重新打开为止;补充:坚持定时器的原理是简单的,当TCP服务器收到了客户端的0滑动窗口报文的时候,就启动一个定时器来计时,并在定时器溢出的时候向向客户端查询窗口是否已经增大,如果得到非零的窗口就重新开始发送数据,如果得到0窗口就再开一个新的定时器准备下一次查询。通过观察可以得知,TCP的坚持定时器使用1,2,4,8,16……64秒这样的普通指数退避序列来作为每一次的溢出时间。

糊涂窗口综合症

TCP的窗口协议,会引起一种通常叫做糊涂窗口综合症的问题,具体表现为,当客户端通告一个小的非零窗口时,服务器立刻发送小数据给客户端并充满其缓冲区,一来二去就会让网络中充满小TCP数据报,从而影响网络利用率。对于发送方和接收端的这种糊涂行为。

再次补充:

TCP通过让接收方指明希望从发送方接收的数据字节数(即窗口大小)来进行流量控制。如果窗口大小为 0会发生什么情况呢?这将有效地阻止发送方传送数据,直到窗口变为非0为止。TCP不对ACK报文段进行确认, TCP只确认那些包含有数据的ACK报文段。如果一个确认丢失了(这个确认是”接收方“向”发送方“发送的ACK,通知”发送方“自己的窗口已经非0了),则双方就有可能因为等待对方而使连接终止:接收方等待接收数据(因为它已经向发送方通告了一个非 0的窗口),而发送方在等待允许它继续发送数据的窗口更新。为防止这种死锁情况的发生,发送方使用一个坚持定时器 (persist timer)来周期性地向接收方查询,以便发现窗口是否已增大。这些从发送方发出的报文段称为窗口探查 (window probe)。

(3)保活计时器:keeplive timer

每当服务器收到客户的信息,就将keeplive timer复位,超时通常设置2小时,若服务器超过2小时还没有收到来自客户的信息,就发送探测报文段,若发送了10个探测报文段(没75秒发送一个)还没收到响应,则终止连接。

补充:

保活定时器更加的简单,还记得FTP或者Http服务器都有Sesstion Time机制么?因为TCP是面向连接的,所以就会出现只连接不传送数据的“半开放连接”,服务器当然要检测到这种连接并且在某些情况下释放这种连接,这就是保活定时器的作用。其时限根据服务器的实现不同而不通。另外要提到的是,当其中一端如果崩溃并重新启动的情况下,如果收到该端“前生”的保活探察,则要发送一个RST数据报文帮助另一端结束连接。

(4)时间等待计时器:Time_Wait Timer

在连接终止期使用,当TCP关闭连接时,并不认为这个连接就真正关闭了,在时间等待期间,连接还处于一种中间过度状态。这样就可以时重复的fin报文段在到达终点后被丢弃,这个计时器的值通常设置为一格报文段寿命期望值的两倍。

补充:

2MSL定时器:MSL是报文段做大生存时间(Maximum Segment Lifetime),设置这个定时器有两个目的:其一是为了测量连接处于TIME_WAIT状态的时间.这样可以让TCP再次发送最后的ACK以防止这个ACK丢失(如果丢失,另一端会重传FIN)。其二,为允许老的重复分节在网络中消逝。具体可以解释为,如果一个TCP连接在断开之前有迷途分节尚未消逝,在断开该TCP连接之后立刻重启一个同样的连接(双方的IP地址和端口port相同),这时之前的迷途的老分节可能对新的新的TCP连接接收,从而造成未定义的错误。为了避免这种情况,TCP规定在TIME_WAIT状态,不能启动一个连接的化身。既然TIME_WAIT状态维持2MSL,这就保证了一个连接上的分组及其应该在 2MSL内都会消失。

TCP的拥塞控制

就和告诉公路一样,车多了会堵车,数据多了,网络也会堵车,甚至还会丢车;

那么TCP为了在堵车的情况下依然保证可靠性传输必然要做一些措施,不然在网络堵车的情况下依然快速发数据的话只会雪上加霜,下面就复习一下几种拥塞控制的方法:

  1. 慢开始
  2. 拥塞避免
  3. 快重传
  4. 快恢复

与其说这是四种方法,我觉得更好的理解这是四种状态,四个阶段;

慢开始和拥塞避免

发送方维护一个拥塞窗口,不同于发送窗口,拥塞窗用于拥塞控制,但是发送窗口一般等于拥塞窗口,有时接收方的接受能力太小,发送窗口还会小于拥塞窗口;

如何确定网络发生拥塞?

如果频繁的出现重传和丢包的现象,那么就有可能网络拥塞,但是刚开始的时候并没有发送数据,该如何确定发送数据的字节大小呢?

慢开始,由小到大增加发送窗口大小,也就是拥塞窗口的值,其实这里的慢也不是很慢,因为是以2的指数的形式增长的;假设我们以报文段为单位,刚开始拥塞窗口的值 cwnd = 1, 发送报文w1,收到w1的确认后,cwnd增加一,此时可以发送2个报文段,当收到这两个报文段的确认后,cwnd增长到4,就以2的指数开始增长;

但是总不能让拥塞窗口这么一直增长下去,这时候就有一个叫做慢开始门限的值 ssthresh ,当cwnd < ssthresh 时使用慢开始算法,当cwnd > ssthresh时停止使用慢开始算法,改为拥塞避免算法,当cwnd == ssthresh时二选一;

那么此时肯定都很好奇这个门限值到底是如何规定的?

一般慢开始的门限值设为16个报文段的大小(一个MSS == 1460字节);

当cwnd的大小达到门限值后,就要进入拥塞避免阶段了,那么拥塞避免到底是如何处理的?

拥塞避免是使拥塞窗口呈线性增长,即从原先的乘法增大变为现在的加法增大,即每经过一个往返时间,cwnd的值增加1;

值得一提的是,一旦检测到网络拥塞,此时会将门限值更新为发送窗口的一般,然后cwnd的值重新置为1,重新开始慢开始算法;

快重传和快恢复

快重传的实现是这样的,当接收方收到一个失序的报文段,立马发送一个重复的确认报文,而不是等发送数据时捎带,这样可以尽快的让发送方知道,当发送方连续收到三个重复的确认报文,不论重传计时器是否到时间,立马重传丢失的报文段;

快恢复是配合快重传的算法,既然连续收到三个重复的确认,不难判断此时网络出现了拥塞,那么此时不但要快重传还要想办法减缓网络压力,此时快恢复算法就来了;

快恢复:当发送方连续收到三个重复的确认时,就进入拥塞避免阶段,并且把门限值减半;

至于应用层的协议就特别多了,下一篇博客将解析我自己写的一个web服务器,基于http协议的,来进行应用层和网络编程的学习;

原创粉丝点击