传输层协议(TCP与UDP)

0x00.网络真相与TCP/IP

国际标准化组织(ISO)于1977年制定的OSI七层参考模型(Open System Interconnection Reference Model )是理论的模型,TCP/IP是事实上的国际标准。

TCP/IP协议模型(Transmission Control Protocol/Internet Protocol),包含了一系列构成互联网基础的网络协议,是Internet的核心协议。

如图是OSI七层模型与TCP/IP模型对照

资源访问出错

在实际应用中,会话层的功能由传输层完成,表示层和应用层合起来称作应用层;网络层为主机提供逻辑通信,而传输层为主机中的应用进程提供端到端的逻辑通信。

  • 逻辑:通过软件处理与控制的,如IP地址和端口号。
  • 数据链路层用物理通信:通过硬件处理与控制的,如MAC地址是由硬件电路加装传输识别的。

关于TCP/IP协议的更多内容,可以参考这篇非常棒的文章

从字面意义上讲,有人可能会认为 TCP/IP 是指 TCP 和 IP 两种协议。实际生活当中有时也确实就是指这两种协议。然而在很多情况下,它只是利用 IP 进行通信时所必须用到的协议群的统称。具体来说,IP 或 ICMP、TCP 或 UDP、TELNET 或 FTP、以及 HTTP 等都属于 TCP/IP 协议。他们与 TCP 或 IP 的关系紧密,是互联网必不可少的组成部分。TCP/IP 一词泛指这些协议,因此,有时也称 TCP/IP 为网际协议群。

资源访问出错
运输层即传输层

资源访问出错
运输层即传输层


0x01.传输层TCP协议

传输层协议

TCP/IP 中有两个具有代表性的传输层协议,分别是 TCP 和 UDP。

  • TCP 是面向连接的、可靠的流协议。流就是指不间断的数据结构,当应用程序采用 TCP 发送消息时,虽然可以保证发送的顺序,但还是犹如没有任何间隔的数据流发送给接收端。TCP 为提供可靠性传输,实行“顺序控制”或“重发控制”机制。此外还具备“流控制(流量控制)”、“拥塞控制”、提高网络利用率等众多功能。
  • UDP 是不具有可靠性的数据报协议。细微的处理它会交给上层的应用去完成。在 UDP 的情况下,虽然可以确保发送消息的大小,却不能保证消息一定会到达。因此,应用有时会根据自己的需要进行重发处理。
  • TCP 和 UDP 的优缺点无法简单地、绝对地去做比较:TCP 用于在传输层有必要实现可靠传输的情况;而在一方面,UDP 主要用于那些对高速传输和实时性有较高要求的通信或广播通信。TCP 和 UDP 应该根据应用的目的按需使用。

TCP协议的功能

保证传输的可靠性(确认,重发,自动重发),流量控制,拥塞控制。

三次握手

在发送端进程(客户端进程)与接收端进程(服务器端进程)之间建立连接(互相发送3个数据包),面向连接的服务

  • TCP 提供面向有连接的通信传输。面向有连接是指在数据通信开始之前先做好两端之间的准备工作。
  • 所谓三次握手是指建立一个 TCP 连接时需要客户端和服务器端总共发送三个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发。

资源访问出错

SYN:同步标志(Synchronize)

ACK:确认标志(Acknowledgement)

RST:复位标志

URG:紧急标志(urgent)

PSH:推标志

FIN:结束标志

  1. 第一次握手:客户端将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给服务器端,客户端进入SYN_SENT状态,等待服务器端确认。
  2. 第二次握手:服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。
  3. 第三次握手:客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。

TCP需要三次握手,UDP却不需要

如果读者对比一下 UDP 的通信流程和 TCP 的通信流程, 可以发现, 在 UDP 协议中, 是没有握手这个操作的。

资源访问出错


这里就引出了 TCP 与 UDP 的一个基本区别, TCP 是可靠通信协议, 而 UDP 是不可靠通信协议。

  • TCP 的可靠性含义: 接收方收到的数据是完整, 有序, 无差错的。
  • UDP 不可靠性含义: 接收方接收到的数据可能存在部分丢失, 顺序也不一定能保证。

TCP为什么是三次握手

  1. 两次握手只能保证单向连接是畅通的。
  2. 采用2次握手,如果由于网络延迟客户端在发出连接请求后在规定的时间内收不到应答会再次发送连接请求包,服务器端会收到2个连接请求包并发送2个应答包同时建立2个连接,这样在服务器端就浪费了系统资源。如果采用3次握手,服务器端在收到客户端的2个连接请求包后会发送2个应答请求包,客户端在收到2个应答请求包后只发送一个应答包,服务器端只能收到客户端的一个应答包(第3次握手包),服务器端只有在收到第三个握手包才建立连接。

四次挥手

  • 四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。
  • 由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

资源访问出错

  • 中断连接端可以是客户端,也可以是服务器端。
  • 第一次挥手:客户端发送一个FIN=M,用来关闭客户端到服务器端的数据传送,客户端进入FIN_WAIT_1状态。意思是说”我客户端没有数据要发给你了”,但是如果你服务器端还有数据没有发送完成,则不必急着关闭连接,可以继续发送数据。
  • 第二次挥手:服务器端收到FIN后,先发送ack=M+1,告诉客户端,你的请求我收到了,但是我还没准备好,请继续你等我的消息。这个时候客户端就进入FIN_WAIT_2 状态,继续等待服务器端的FIN报文。
  • 第三次挥手:当服务器端确定数据已发送完成,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。服务器端进入LAST_ACK状态。
  • 第四次挥手:客户端收到FIN=N报文后,就知道可以关闭连接了,但是他还是不相信网络,怕服务器端不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。最终完成了四次握手。

TCP报头结构

资源访问出错

  • 源端口号,目标端口号:各2各字节。
  • 确认号:acknowledgement number期待发送的字节地址编号。假设确认号为N ,表示第N个字节之前的数据已收到。
    • 假设包中DATA长度为1000字节,发送数据的起始内存地址为1
    • 示例:
    • 包的序号 接受方发的确认号
      第一个包 1001
      第二个包 2001
      第三个包 3001
  • 序列号:sequence number:DATA的首字节在发送端内存的地址编号。
  • 校验和(2字节):checksum 将(tcp报头+DATA)作为校验内容(其中填充位与16位校验和的内容置为“0”),转换为一系列16位比特的补码,求和, 和的补码即:校验和。在接收端对接收到的TCP报头及DATA执行同样的运算,结果为“0”,说明接受到的内容正确。
  • 头长度:Data offset ,tcp报头距data首字节的位移量,单位:32比特。
  • 保留:reserved为将来扩展准备的域,6位 全为0。
  • 协议控制标志(6位):URG:urgent ; 包中含紧急数据;PSH : push,发送端的进程要求接收端进程收到数据后马上应答 ; RST : reset ,连接出错,重新建立连接;SYN :synchronize ; FIN :finish ; ACK:acknowledge;
  • 可选域:options; 为了提高TCP协议的性能而设定的,如:连接时传递的4字节的MSS(数据包中data部分的最大长度)
  • 窗口大小(16位):接收端可接受数据的多少,单位:字节
  • 紧急指针:从data开始有多少个字节的数据是紧急数据。

滑动窗口

为了提高传输效率与实现流量控制采用滑动窗口协议。

大家都知道,我们从一台机器向另外一台机器发送数据的时候,数据并不是一口气也不可能一口气传输给接收方。这个并不难理解,因为网络环境特别的复杂,有些地方快有些地方慢。所以,操作系统把这些数据写成连续的数据包,并且以一定的速率发给对方。一定的速率怎么理解呢?网络环境就像复杂的交通链路。就好比一个沙漏,中间可能有一个地方流量非常的小,这个最小的口径决定了网络传输的真正速度。我们要考虑到带宽缓冲区等因素,如果一下子发送所有的数据只会加大网络压力,造成丢包重试,轻则传输更慢,重则网络崩溃。因为TCP是顺序发送的,操作系统将这些数据包一批一批的发送给对方,就像一个窗口,不停地往后移动,所以,我们称之为TCP滑动窗口协议。

在TCP中,窗口的大小是在TCP三次握手后协定的,并且窗口的大小并不是固定的,而是会随着网络的情况进行调整。这个也不难理解,原本你女朋友在家独享10M的宽带,你下班要上虎牙看直播,两个人就要共享这个宽带。TCP为了更好的传输效率,就会调整窗口的大小。

资源访问出错

我们通过一个图来解释下滑动窗口的工作流程,对于发送端来说,即将要发送的数据包排成一个队列,对于发送者来说,数据包总共分成四类。分别是在窗口前的,已经发送给接收方,并且收到了接收方的答复,我们称之为已发送。在窗口中的,有两种状态,一个是已经发送给接收方,但是接收方还没确认送达,我们称之为已发送未确认,另外一个是可以发送了,但是还没有发送,我们称之为允许发送未发送。最后的是在窗口外面的,我们称之为不可发送,除非窗口滑到此处,否则不会进行发送。

就这样,一旦前面的数据已经得到服务端确认了,这个窗口就会慢慢地往后滑,P1,P2两个数据包被确认之后,窗口就往后移动,后面新的数据包就由不可发送待发送变成了可发送状态了。

如果长时间得不到确认,就会超时重发。

参考文章一篇带你读懂TCP之“滑动窗口”协议

MSS段长

MSS:Maximum Segment Size ,传输层允许的最大段长。

MSS=IP协议不进行分段处理的最大段长(MTU)-IP包头的长度- TCP报头长度。

MSS在连接时确定。

MTU=IP包头+传输层报头+DATA;

MSS=DATA长度。

IP报头长度=20字节。TCP报头长度:发送数据时=20字节,连接时=24字节,
连接时,在它的报头可选域(options)中加入了4字节的MSS(接收端允许的DATA的长度)

如以太网:
它的MSS=1500(MTU=1500)-20(IP报头长度=20字节)-20(TCP报头长度)。

为了提高传输效率,发送方不必等待应答包,可连续发送多个包,接收端只发一个应答包。可连续发送的字节数量为窗口大小。窗口大小,由往返时间与接收端缓冲区大小动态决定。窗口大小/DATA长度=连续发包的数量。窗口大小以字节为单位。

慢启动法

发送方一开始假定窗口大小为1 MSS(等待应答包的时间为T),如果在T周期内能收到应答包,则将窗口大小设为2 MSS,在应答包中包含接收端根据自己缓冲区大小设定的最大允许窗口大小值X ,发送方在2 MSS与X之间选一个较小数Y作为窗口大小,继续发送。
如果在T周期内能收到应答包, 则将窗口大小设为Y=2*Y, 在应答包中包含接收端根据自己缓冲区大小设定的最大允许窗口大小值X, 发送方在Y与X之间选一个较小数Y (Y= MIN(Y , X)作为窗口大小,继续发送。以此类推。如果在T周期内能收不到应答包,则将Y设为拥塞窗口大小,下次发送时窗口大小为Y=Y/2发送。

为了避免接收端出现拥塞采用慢启动法。

流量控制

流量控制:往往指点对点通信量的控制,是个端到端的问题。发送端的流量由接收端缓冲区大小控制。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。

拥塞控制

数据包的往返时间是拥塞控制的核心要素。

拥塞控制就是防止过多的数据注入到网络中,使网络中的路由器或链路不致过载。

拥塞控制是一个全局性的过程,涉及到所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素。

几种拥塞控制方法:慢启动、拥塞避免、快重传、快恢复。

资源访问出错

慢启动阈值(Ssthresh );窗口大小的限定值,初始值设为16MSS。数据发送过程中它可以动态调整。发送拥塞时,调整Ssthresh=cwnd/2。cwnd是拥塞发生时,发送端窗口大小值(在这儿cwnd为连续发包的个数,用连续发包的个数表示窗口大小)。

  • 慢启动:窗口大小一开始设为1MSS。慢启动指定是窗口大小一开始是最小的。

    当窗口大小小于Ssthresh(初始值为16MSS)时:发送端在规定的时间内能收到接收端的应答包,窗口大小翻倍,让发送端窗口大小X=Min( 2*X,接收端缓冲区大小)作为新的窗口大小继续发送;发送端在规定的时间内收不到接收端的应答包,窗口大小减半,让发送端窗口大小X=Min(X/2,接收端缓冲区大小)作为新的窗口大小继续发送。
  • 拥塞避免:当窗口大小>Ssthresh时,发送端在规定的时间内能收到接收端的应答包,这时采用拥塞避免算法,发送端窗口大小X每次增加1MSS。X的增量不是翻倍的。让X=Min( X+1,接收端缓冲区大小)作为新的窗口大小继续发送。

    当发送端在规定的时间内收不到接收端的应答包时,表明拥塞已经发生,在本例中假定cwnd=24。调整Ssthresh=cwnd/2, 窗口大小重新设为1,重新从慢启动开始继续。
  • 快重传:让发送端尽早知道个别报文的丢失。快重传算法要求接收端对收不到的报文马上确认(收不到第N+1个包,要确认第N个包),如果发送端收到3个一样的确认包,立即进行重传(如收到第N个包的三个确认包,发送端马上发送从第N+1个包开始的数据包,发送的包的数量等于此时的窗口大小)。在图中④点。
  • 快恢复:在图中④点,发送端发现只是丢失了个别报文,不是网络中真正出现了拥塞,于是不使用慢启动,而是使用快恢复算法,让Ssthresh= Ssthresh初始值 /2(Ssthresh=16/2),把窗口大小设为Ssthresh(在此为8),从⑤点开始执行拥塞避免算法。

只有在丢包的情况下才使用快重传与快恢复。快恢复是快重传的后续操作。

重发控制,重复控制

重发定时器,发送方在规定的时间(重发超时)内收不到应答包,则自动重发。

接收端收到错误的包,不做任何处理。

重发超时:等待应答包的时间。

重复控制:由于数据包在网络中延时,发送端在重发超时周期内收不到应答包,发送端自动重发,结果接受端收到2个同样的包,接受端对收到的重复包要删除。

捎带(piggyback)

在确认包中包含数据。


0x02.传输层UDP协议

UDP协议的功能

非连接型服务,不可靠传输协议;传输多媒体数据,网络管理命令。

管理机与被管理机之间不能采用TCP协议,只能采用UDP协议,因为被管理机可能关机或故障。

UDP报头结构

资源访问出错

校验和 :checksum 将UDP段(报头+报文,填充位与校验和的内容为“0”)的内容转换为一系列16位比特的补码,求和, 补码的和即:校验和。

UDP的报头有8个字节。


0x03.端口号

端口号用16位二进制数表示(216=65535),服务器端使用的端口号有:熟知端口号或系统端口号(0~1023),IANA(Internet Assigned Numbers Authority)将它分派给TCP/IP最重要的一些应用程序。如:

应用程序 FTP TELNET DNS TFTP HTTP SNMP HOSTNAME
端口号 21-20 23 25 53 80 161 101

资源访问出错

另一类叫做登记端口号(1024~49151),必须在IANA按规定登记,以防止重复。

客户端使用的端口号(49152~65535)。

欢迎请我喝奶茶(*゜ェ゜*)
---这篇文章到头了---感谢您的阅读-------------