TCP/IP协议
TCP/IP协议模型
各层常见协议
1.链路层:
ARP:地址解析协议,根据IP地址获取真实物理地址MAC地址的一种协议。当主机需要发送一个IP包时,会查本地高速缓存,若不存在,主机便会发送一个ARP包,从含有该IP映射的主机中获取相关的ARP包。解包后会更新本地ARP缓存。
RARP:与ARP协议相反。
2.网络层:
IP协议:TCP/IP协议的核心,所有的传输层协议以及IP辅助协议都以IP数据格式传送。IP协议是不可靠的,TCP可靠的原因是加入了多种机制,保证可靠传输。换而言之,IP协议只负责IP数据传送,不保证安全性。
ICMP协议:IP辅助协议,全称网络控制报文协议。正如前文所述,IP协议是不可靠的传输。ICMP协议就是用来封装IP数据包传输错误时的信息(如主机不可达等),并将其传送回主机。
3.传输层:
TCP协议:面向连接(客户端与服务端建立起端到端的全双工通信)的传输层协议,采用字节流方式,传输可靠,但速度慢。
UDP协议:无连接(广播式)的传输层协议,采用报文方式,传输不可靠可能丢包,但速度快。
4.应用层协议:
Http协议:超文本传输协议,端口号80。默认采用TCP协议实现。所以Http的请求过程首先要建立TCP连接(三次握手),然后客户端发出Http请求,服务端处理请求并响应。
Https协议:Http协议基础上进行了加密,端口443。由于用来加密的原因,所以在发生请求前需要进行加密。更多次的握手保证了数据的安全性,但同时也降低了效率。
其他常见:
IP地址
IP地址一共32位,一共五类IP地址。
IP数据包的封装
封装过程:(Http为例)
IP数据报:(建议每32bit按行的方式去理解)
四个字节共32Bit的数据按每次8Bit传输。(每一行)
版本号代表当前IP协议的版本如IPV4或IPV6,头部长度代表首部占32Bit(4个字节)的数目,包含可选选项,四个位表示首部最长1111=15(行)即4*15=60个字节,没有任何选项的即图中所示默认为5(行)即4*5=20个字节。(如图所示的前五行)
服务类型包含一个3Bit的优先权字段,4Bit的Tos字段以及末尾1Bit的置零字段。TOS字段包含四个选项最小时延、最大吞吐、最高可靠、最小费用。
总长度代表的是整个IP数据包的长度,以字节为单位,则最长为65535。但由于MTU(最大传输单元)的存在,有可能会被分片。同时利用总长度和首部长度可知数据的起始位置。
TTL生存时间字段设置可经过的最大路由器数,每经过一个路由器就减一。当该字段为0时,就丢弃该报文,并通过ICMP协议返回相关信息。TraceRoute就是通过这个原理实现的,先设置TTL为1尝试,然后为2直至通路为止,由此获得所有的路由信息。
Ping、TraceRoute和DNS
Ping:基于ICMP协议的应用程序。前文可知ICMP包含报文传输过程中的错误,所以根据这一信息可以测试主机间的联通状态
TraceRoute:通过将TTL从一递增的设置数据包尝试,直至获取所有路由表的程序。
DNS协议:域名解析服务,类似于ARP协议。ARP时IP与MAC地址的映射,DNS则是域名与IP地址的映射。
TCP连接的建立与断开。
预备知识:
TCP头部结构:
五个关键位置:
SYN:建立连接标识,ACK:响应标识,FIN:断开连接标识,seq(seq number):发送序号,ack(ack number):响应序号。
从图可知FIN、ACK、SYN三个标志位只有1Bit要不为0,要不为1,而seq和ack支持32bit。
1.三次握手(建立连接):
客户端发送SYN,seq=x,进入SYN_SEND状态。
服务端响应SYN,ACK,seq=y,ack =x+1,进入SYN_RCVD状态。
客户端回应ACK,seq=x+1,ack=y+1.进入ESTABLISHED状态,服务端收到也进入该状态。
简而言之:A告诉B建立连接,B收到后告诉A我收到了建立连接的消息,然后A收到后通知B你给我的确认我收到了。
三次握手的原因:
为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
2.四次挥手(断开连接):
主机A发送FIN,ACK,seq=x,ack=z,进入FINWAIT_1状态。
主机B回应ACK,seq=z,ack=x+1,主机A收到后进入FINWAIT_2状态。
主机B发送FIN,ACK,seq=y,ack=x,进入LAST_ACK状态。
主机A回应ACK,seq=x,ack =y进入TIME_WAIT状态,等待主机B收到后关闭连接,进入Closed状态。
简而言之:A告诉B我已经没有数据要传输了,B发送响应我同意你的关闭请求。然后B在请求A关闭连接,B收到请求后,发送确认关闭连接的响应。如果2MSL没收到回复,证明B已关闭。
四次挥手的原因:
TCP是全双工模式,这就意味着,当主机A发出FIN报文段时,只是表示主机A已经没有数据要发送了,但是,这个时候主机A还是可以接受来自主机B的数据;当主机B返回响应ACK报文段时,表示它已经知道主机A没有数据发送了,但是主机B还是可以发送数据到主机A的;当主机B也发送了FIN报文段时,这个时候就表示主机B也没有数据要发送了,就会告诉主机A,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
为什么要等待2MSL(MSL是指报文最大生存时间):
1.保证全双工通信的TCP协议可靠关闭。
2.保证这次连接的重复数据段从网络中消失
TCP协议可靠性的几个方面
1.超时重传
原理:在发送数据报文后开启一个计时器,如果超过了时间仍没有收到ACK回应就重发该数据报文。直到成功为止。
RTO:重传超时时间,该值影响超时重传的效率。若过长,效率低,若过短,则会导致网络更加拥塞,导致更多的超时和重传。
RTT:连接往返时间,即一个TCP数据包发送到接收到相应的响应时间,例如游戏中的延迟。
RTO最好是RTT的时间,但由于RTT不固定,所以使用自适应算法。
2.流量控制
意义:解决接收端处理数据不如发送端发送数据快,导致数据过多无法处理。
实现原理:滑动窗口机制。通过ACK报文响应窗口值的大小表示当前缓存可以接受的数据报文大小,由此实现控制客户端发送报文大小,从而实现流量控制。
3.拥塞控制
意义:为了避免发送方因为IP网络拥塞而遏制。
解决的几种方法:慢启动、拥塞避免、快重传、快恢复。
拥塞窗口概念:类似于滑动窗口,但限制的是本机发送的大小(cwnd),若网络拥塞则该值小,若不拥塞则该值大(即动态变化,取决于网络情况)。通过不同的算法控制拥塞窗口的大小从而尽量减少拥塞的出现。
慢开始算法:开始由于不知道网络情况,为了防止在网络拥堵的情况下注入过多数据,所以开始的cwnd值较小然后逐渐增加。最初设置为MSS(最大报文长度)每经过一个轮次(服务端对客户端的每个报文的确认响应)加一。列入最初为1,发送一个报文,收到一个确认,cwnd为2,然后发送两个报文,收到两个确认,cwnd变为4。所以慢开始指的不是增长速率慢,而是cwnd的初始值小。
为了避免cwnd增长过快,需要使用ssthresh变量设置cwnd的门限。当cwnd小于ssthresh时使用慢开始算法。当cwnd大于ssthresh时,停止使用慢开始算法,改用拥塞避免算法,二者相等时,两个算法皆可以使用。注意,当发生网络拥塞时ssthresh会变为当前cwnd值的一半(乘法缩小算法),拥塞窗口设置为1。然后重新开始慢开始算法,直至cwnd=ssthresh时执行拥塞避免算法。
拥塞避免算法:每经过一个RTT往返就加一,这样cwnd变为线性增长而非起始的成倍增长,增长速率相对于慢开始放缓。并非完全避免拥塞,只是通过限制cwnd的大小增长塑速率减少了网络拥塞的可能性。
快重传与快恢复:在超时重传中,主要是由于超过了定时器的限制,才进行重传。快重传重新定义了一种丢包标准,即如果连续三次收到重复ACK包即认为该seq(序列)包丢失,然后立即进行重传。而快恢复算法一般与快重传算法一起使用。当收到三个重复ACK包时,就进行乘法缩小算法,把ssthresh减半(减半为拥塞发生时的cwnd的值的一半,不开始慢开始算法,cwnd不置零,设置为ssthresh值的一半,然后执行拥塞避免算法使cwnd线性增长)
TCP的定时器
重传定时器:前文中保证TCP可靠传输的超时重传机制使用的定时器,当发送报文后开始计时,若没有在定时器结束前收到ACK包,则代表数据丢失,进行重传,避免陷入无限等待。
坚持定时器:对付零窗口通知设立。以滑动窗口为例,当从零窗口恢复时,接受端发送一个非零的ACK包,而ACK包没有对应的响应,若此ACK包丢失,则发送端仍认为为零窗口状态,而接收端不会重新发送非零的ACK包,则陷入死循环状态。解决方法就是在发送端确认窗口为0时实力该计时器,计时结束发送探测报文告知接收端重发ACK包,并每个一段时间将该计时器重置哦,直至出现非零窗口。
保活计时器:防止TCP连接出现长时间的空闲,一般设置为两个小时。如果某端因为出现了故障,两个小时后另一端发送10个探测报文(每个间隔一段时间)没有收到回复则直接断开TCP连接,而非通过四次挥手断开连接。
时间等待计时器:TCP连接断开时四次挥手使用的计时器。即等待2MSL后关闭主动关闭一端的连接。