TCP协议简析

OSI七层模型与TCP/IP五层模型

OSI(Open System Interconnect),即开放式系统互联模型是ISO(国际标准化组织)组织在1985年发布的网络模型,其结构以下:html

image-20190503131546100

其中的表示层负责提供各类用于应用层数据的编码和转换功能, 会话层负责创建、管理和终止表示层实体之间的通讯会话. 这两层在TCP/IP模型中整合到了应用层.因此咱们经常使用的TCP/IP模型通常只讨论5层:算法

image-20190503131508854

能够看到从应用层发出的数据,每通过一层都会添加上该层特有的header,终端收到数据包以后又会一层层解除头部拿到原始数据:缓存

图片摘自阮一峰的博客 http://www.ruanyifeng.com/blo...

net协议

物理层

物理层, 为数据端设备提供传送数据的通路。能够双向通讯,为数据传输提供可靠的环境。对应咱们的网线、光纤(物理设备)。网络

这一层不详细展开了,只说下物理层通讯原理的一个重要概念:并发

  • 单工:单向通道,只能单向通讯。好比广播。
  • 半双工:双向通道,但同一时间点只能一方通讯。好比对讲机。
  • 全双工:双向通道,相互通讯。互不干扰。好比:电话。

数据链路层

数据链路层在两个网络实体之间提供数据链路链接的建立、维持和释放管理。tcp

数据链路层只负责数据的封装成祯和透明传输,不保证祯的可靠性,可靠性是tcp协议实现的post

数据链路层职责:大数据

  • 封装成帧编码

    将网络层交付下来的ip数据报的先后添加首部和尾部,封装成帧。首部和尾部的重要做用是进行帧定界。为了提升传输效率,须要尽可能增大数据部分的长度,可是每一个链路层协议都规定了帧数据部分的长度上限,最大传输单元MTU(Maximum Transfer Unit)。当数据是可打印的ASCII码,帧定界能够用特殊的帧定界符SOH(Start of Header)(00000001)和EOT(End of Transmission)(00000100)spa

    image-20190503134026958
    帧的最大长度为1522字节,其中1500字节是payload:

    图片摘自阮一峰的博客 http://www.ruanyifeng.com/blo...

    net_package

  • 透明传输
  • 传输的数据中任何8比特的组合不容许和帧定界的控制字符比特同样,不然会出现帧定界错误。文本文件不会产生这样的问题,能够实现透明传输。可是若是是二进制文件,可能会找到错误的帧边界。解决方法是采用字节填充。在SOH和EOT的前面加上转义字符ESC(1B),若是数据中存在转义字符,就在转义字符前插入个转义字符(11011)
  • 差错控制
    使用循环冗余检验CRC(Cyclic Redundancy Check),添加帧检验序列FCS(Frame Check Sequence)

    差错校验保证传递过来的帧无差错,可是数据链路层不提供可靠服务,仍是存在帧丢失、帧重复、帧失序的问题

网络层

网络层提供路由和寻址的功能,使两终端系统可以互连且决定最佳路径,并具备必定的拥塞控制和流量控制的能力。

网络层常见协议有IP,ICMP,OSPF,EIGRP,IGMP等

传输层

常见的协议有TCP,UDP等

TCP 是一种面向链接的协议,它给用户进程提供可靠的全双工的字节流。确保数据包的可靠,有序,以及支持流量控制。

一个TCP包最长1480字节,payload大概1460左右.所以,一条1500字节的信息须要两个 TCP 数据包。HTTP/2 协议的一大改进, 就是压缩 HTTP 协议的头信息,使得一个 HTTP 请求能够放在一个 TCP 数据包里面,而不是分红多个,这样就提升了速度。

tcp和udp的区别

  • tcp是面向链接的,也就是说,在收发数据前,必须和对方创建可靠的链接。upd是无链接的,传输数据以前源端和终端不创建链接, 当它想传送时就简单地去抓取来自应用程序的数据,并尽量快地把它扔到网络上。
  • tcp是可靠的,而udp是不可靠的,upd不保证数据不丢失,也不保证package顺序,可靠性只能经过上层应用把控
  • tcp由于是面向链接的,因此只能点对点传输,而upd由于不创建连接不须要维护状态,能够广播
  • udp信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。

可见udp更适合对实时性要求高的广播而tcp适合可靠传输

应用层

是OSI参考模型的最高层,它是计算机用户,以及各类应用程序和网络之间的接口,其功能是直接向用户提供服务,完成用户但愿在网络上完成的各类工做。

常见协议HTTP,FTP,SNMP等

TCP协议

SEQ

tcp包在发送时会为每个包编号,称为sequence number(SEQ),以便接收的一方按照顺序还原。万一发生丢包,也能够知道丢失的是哪个包。
包的下一个seq即next seq=seq+payload 好比当前seq=1,payload长度为1400,那下一个seq就应该是1401.

ack

ack是acknowledgement的缩写,表明确认的意思.须要注意的是ack=n 表明着确认seq<=n-1的包正常接收.

三次握手

TCP是面向链接的,不管哪一方向另外一方发送数据以前,都必须先在双方之间创建一条链接。在TCP/IP协议中,TCP协议提供可靠的链接服务,链接是经过三次握手进行初始化的。三次握手的目的是同步链接双方的序列号和确认号并交换 TCP窗口大小信息。

三次握手的图示以下:

image-20190503222544384

wireshark抓包演示:

image-20190503214011085

  • 第一次client发起链接,发送一个SYN包表示创建链接,能够看到此时seq=0,payload长度也是0
  • 第二次server对client应答,并发送链接请求. 发送一个包flags标志位里既包含syn又包含ack此时ack=x+1=0+1=1 ,seq=0
  • 第三次client接到server的应答后,对server的链接请求作应答,此时ack=y+1=0+1=1
为何须要三次握手?

握手为何是三次?不是两次或者四次?

第一次握手是client发起链接请求,接到后server确认client能正常发送.

第二次握手是server对client的应答,接收到后client确认server能正常接收,且能正常发送

第三次握手是client对server的应答,接收到后server确认client能正常接收

至此,双方就都能确保对方能够正常接收和发送数据,tcp经过三次握手保证了链接的可靠性

四次挥手

tcp链接断开的时候须要四次包发送操做,称为四次挥手:

image-20190503224512958

wireshark抓包示例:
image-20190503223327645

  • 第一次client送一个FIN包和一个seq612,以后client进入FIN_WAIT_1阶段
  • server接收到以后回复一个ack613,和seq945,表示收到了client的关闭请求,以后进入CLOSE_WAIT状态,client进入FIN_WAIT_2状态
  • 以后server处理完本身其余的package以后发送一个FIN(实际用wireshark抓包没看到FIN单独出现的状况,都是伴随着一次ack)和seq945,此时server进入LAST_ACK状态,再也不回复消息.
  • client接收到server的FIN包后回复一个ack946以后进入TIME_WAIT状态,server接收到这个包以后直接进入CLOSED状态,client等待了两个msl(Maximum Segment Lifetime最大报文生存时间)以后没有收到应答,表明server正常关闭,便也进入CLOSED状态,关闭链接.
为何要四次挥手?

为何链接时候只须要三次握手,而断开时须要四次?

由于链接的时候当server端收到client端的SYN链接请求报文后,能够直接发送syn+ack报文,ack用来应答,syn用来请求链接. 可是在关闭的时候server收到client的fin请求不能当即回复fin包,由于server可能还有其余的包没有接收或发送完毕. 因此server端只能先回一个ack,表示收到了client的关闭请求. 而后当server端处理好本身的包以后再发送一个fin报文来请求关闭链接.

滑动窗口

滑动窗口协议(Sliding Window Protocol),属于TCP协议的一种应用,用于网络数据传输时的流量控制,以免拥塞的发生。 该协议容许发送方在中止并等待确认前发送多个数据分组。 因为发送方没必要每发一个分组就停下来等待确认,所以该协议能够加速数据的传输,提升网络吞吐量。

在上面的例子中,咱们都是发送一个包,ack,再发另外一个包.能够看出来,这样的吞吐量并不大,发送端须要等接收端ack一个包以后才能发下一个包.滑动窗口就是为了提升发送效率(一次发送一组package),并控制流量.

发送端的缓存结构以下图所示,下图的缓存分为已发送已ack 已发送未ack 待发送 未发送四块,其中已发送未ack和待发送称为发送窗口.
而接收端缓存(这里没有画)分为已接收 未接收准备接收 未接收不许备接收三块,其中未接收准备接收称为接收窗口

滑动窗口的图懒得画了,直接偷的别人的图: https://juejin.im/post/5c9f1d...

image-20190504135716557

image-20190504135751244

能够看到已发送的package获得了ack确认窗口左端才会向右移一位.

TCP是双工的协议,会话的双方均可以同时接收、发送数据。TCP会话的双方都各自维护一个“发送窗口”和一个“接收窗口”。其中各自的“接收窗口”大小取决于应用、系统、硬件的限制(TCP传输速率不能大于应用的数据处理速率)。各自的“发送窗口”则要和对方的“接收窗口”大小相同

tcp在三次创建链接时就会交换双方的接收窗口大小,借此来肯定发送窗口大小.

在收发过程当中能够随时调整窗口的大小来达到流量控制的目的.

image-20190504144450307

TCP重传

tcp要保证数据可靠性,因此要有丢失重传机制.

tcp的ack机制只会确认连续的最后一个包,好比A发送了1,2,3三个连续的包,B接收到以后会ack4,A拿到这个ack以后就知道B确认接收到了seq=4以前的全部包.

如今假如B没接收到3号包,这时4号包来了,要怎么应答呢? 此时不能应答4号包,不然A就觉得B收到了3

超时重传

一种解决方案是B接收不到3,即便接收到了4也不ack,就在那死等3.而A发现B应答timeout以后会重传3或3及其以后的包.超时重传的缺点是须要等timeout,浪费时间.

快速重传

TCP引入了一种叫Fast Retransmit 的算法,不以时间驱动,而以数据驱动重传

若是包有丢失,接收方就连续ack丢失的那个包,发送方连续三次接收到相同的ack,就重传这个包.

好比上面的例子,B没拿到3号包就会ack3,此时A发来4号包,B仍是ack3.A发来5号包,B继续ack3.

此时A拿到三个ack3就知道3号包丢失,因而立刻重传3号包.B就收到3号包以后直接ack6.表明5号包以前都接收成功.

相关文章
相关标签/搜索