TCP协议详解

一、特点

  1. 基于流的方式。
  2. 面向连接。
  3. 可靠通信。
  4. 在网络状况不佳时候尽量降低系统由于重传带来的带宽开销。
  5. 通信连接维护是面向通信的两个端点的,而不考虑中间网段和节点。

二、协议规定

  1. 数据分片:在发送端对用户数据进行分片,在接收端进行重组,由TCP确定分片的大小并控制分片和重组;
  2. 到达确认:接收端接收到分片数据时,根据分片数据序号向发送端发送一个确认;
  3. 超时重发:发送方在发送分片时启动超时定时器,如果在定时器超时之后没有收到相应的确认,重发分片;
  4. 滑动窗口:TCP连接每一方的接收缓冲空间大小都固定,接收端只允许另一端发送接收端缓冲区所能接纳的数据,TCP在滑动窗口的基础上提供流量控制,防止较快主机致使较慢主机的缓冲区溢出;
  5. 失序处理:作为IP数据报来传输的TCP分片到达时可能会失序,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层;
  6. 重复处理:作为IP数据报来传输的TCP分片会发生重复,TCP的接收端必须丢弃重复的数据;
  7. 数据校验:TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到分片的检验和有差错,TCP将丢弃这个分片,并不确认收到此报文段导致对端超时并重发。

三、首部格式

在这里插入图片描述

在这里插入图片描述

  1. Source Port是源端口,16位。
  2. Destination Port是目的端口,16位。
  3. Sequence Number是发送数据包中的第一个字节的序列号,32位。
  4. Acknowledgment Number是确认序列号,32位。
  5. Data Offset是数据偏移,4位,该字段的值是TCP首部(包括选项)长度除以4。
  6. 标志位: 6位,
    (1)URG表示Urgent Pointer字段有意义:
    (2)ACK表示Acknowledgment Number字段有意义
    (3)PSH表示Push功能,
    (4)RST表示复位TCP连接
    (5)SYN表示SYN报文(在建立TCP连接的时候使用)
    (6)FIN表示没有数据需要发送了(在关闭TCP连接的时候使用)
  7. Window表示接收缓冲区的空闲空间,16位,用来告诉TCP连接对端自己能够接收的最大数据长度。
  8. Checksum是校验和,16位。
  9. Urgent Pointers是紧急指针,16位,只有URG标志位被设置时该字段才有意义,表示紧急数据相对序列号(Sequence Number字段的值)的偏移。

(一)说明

A、TCP端口号

  1. 源端口号和目地端口各占16位两个字节,也就是端口的范围是2^16=65535,另外1024以下是系统保留的,从1024-65535是用户使用的端口范围。

B、TCP序号和确认号

  1. 32位序号 seq:Sequence number 缩写seq ,TCP通信过程中某一个传输方向上的字节流的每个字节的序号,通过这个来确认发送的数据有序,比如现在序列号为1000,发送了1000,下一个序列号就是2000。
  2. 32位确认号 ack:Acknowledge number 缩写ack,TCP对上一次seq序号做出的确认号,用来响应TCP报文段,给收到的TCP报文段的序号seq加1。

C、TCP的标志位

  1. 每个TCP段都有一个目的,这是借助于TCP标志位选项来确定的,允许发送方或接收方指定哪些标志应该被使用,以便段被另一端正确处理。
  2. 用的最广泛的标志是 SYN,ACK 和 FIN,用于建立连接,确认成功的段传输,最后终止连接。
    (1)SYN:简写为S,同步标志位,用于建立会话连接,同步序列号。
    (2)ACK: 简写为.,确认标志位,对已接收的数据包进行确认;
    (3)FIN: 简写为F,完成标志位,表示我已经没有数据要发送了,即将关闭连接;
    (4)PSH:简写为P,推送标志位,表示该数据包被对方接收后应立即交给上层应用,而不在缓冲区排队;
    (5)RST:简写为R,重置标志位,用于连接复位、拒绝错误和非法的数据包;
    (6)URG:简写为U,紧急标志位,表示数据包的紧急指针域有效,用来保证连接不被阻断,并督促中间设备尽快处理;

四、内容

(一)保证数据正确性与合法性

1. 校验和函数,在发送和接收时都要计算校验和

2. MD5认证对数据加密

(二)保证可靠性

1. 超时重传机制

在这里插入图片描述

2. 捎带确认机制

(三)流量控制

参考链接:https://www.cnblogs.com/coder-programming/p/10627746.html

1. 滑动窗口协议,对于窗口内未经确认的分组需要重传。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(四)拥塞控制

1. TCP拥塞控制算法(AIMD算法)

(1)慢启动

每当建立一个TCP连接时或一个TCP连接发生超时重传后,该连接便进入慢启动阶段。进入慢启动后,TCP实体将拥塞窗口的大小初始化为一个报文段,即:cwnd=1。此后,每收到一个报文段的确认(ACK),cwnd值加1,即拥塞窗口按指数增加。当cwnd值超过慢启动阐值(ssthresh)或发生报文段丢失重传时,慢启动阶段结束。前者进入拥塞避免阶段,后者重新进入慢启动阶段。

(2)拥塞避免

在慢启动阶段,当cwnd值超过慢启动阈值(ssthresh)后,慢启动过程结束,TCP连接进入拥塞避免阶段。在拥塞避免阶段,每一次发送的cwnd个报文段被完全确认后,才将cwnd值加1。在此阶段,cwnd值线性增加。
在这里插入图片描述

(3)快速重传

快速重传是对超时重传的改进。当源端收到对同一个报文的三个重复确认时,就确定一个报文段已经丢失,因此立刻重传丢失的报文段,而不必等到重传定时器(RTO)超时。以此减少不必要的等待时间。
在这里插入图片描述

(4)快速恢复

快速恢复是对丢失恢复机制的改进。在快速重传后,不经过慢启动而直接进入拥塞避免阶段。每当快速重传后,置ssthresh=cwnd/2、cwnd=ssthresh+3(另一种快恢复:将ssthresh值和拥塞窗口cwnd值调整为当前cwnd的一半,开始执行拥塞避免算法)。此后,每收到一个重复确认,将cwnd值加1,直至收到对丢失报文段和其后若干报文段的累计确认后,置cwnd=ssthresh,进入拥塞避免阶段。
在这里插入图片描述

五、工作方式

(一)三次握手

在这里插入图片描述

三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。在 socket 编程中,客户端执行 connect() 时。将触发三次握手。

A、过程

  1. 第一次握手:
    客户端将TCP报文标志位SYN置为1,随机产生一个序号值seq=J,保存在TCP首部的序列号(Sequence Number)字段里,指明客户端打算连接的服务器的端口,并将该数据包发送给服务器端,发送完毕后,客户端进入SYN_SENT状态,等待服务器端确认。

  2. 第二次握手:
    服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将TCP报文标志位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状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。

注意:我们上面写的ack和ACK,不是同一个概念:

  1. 小写的ack代表的是头部的确认号Acknowledge number, 缩写ack,是对上一个包的序号进行确认的号,ack=seq+1。
  2. 大写的ACK,则是我们上面说的TCP首部的标志位,用于标志的TCP包是否对上一个包进行了确认操作,如果确认了,则把ACK标志位设置成1。

B、原因

我们假设client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。

本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。

假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。

所以,采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。

TCP 三次握手跟现实生活中的人与人打电话是很类似的:

三次握手:
“喂,你听得到吗?”
“我听得到呀,你听得到我吗?”
“我能听到你,今天 balabala……”

经过三次的互相确认,大家就会认为对方对听的到自己说话,并且愿意下一步沟通,否则,对话就不一定能正常下去了。

(二)四次挥手

在这里插入图片描述

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

A、过程

  1. 第一次挥手:
    Client端发起挥手请求,向Server端发送标志位是FIN报文段,设置序列号seq,此时,Client端进入FIN_WAIT_1状态,这表示Client端没有数据要发送给Server端了。
  2. 第二次挥手:
    Server端收到了Client端发送的FIN报文段,向Client端返回一个标志位是ACK的报文段,ack设为seq加1,Client端进入FIN_WAIT_2状态,Server端告诉Client端,我确认并同意你的关闭请求。
  3. 第三次挥手:
    Server端向Client端发送标志位是FIN的报文段,请求关闭连接,同时Client端进入LAST_ACK状态。
  4. 第四次分手 :
    Client端收到Server端发送的FIN报文段,向Server端发送标志位是ACK的报文段,然后Client端进入TIME_WAIT状态。Server端收到Client端的ACK报文段以后,就关闭连接。此时,Client端等待2MSL的时间后依然没有收到回复,则证明Server端已正常关闭,那好,Client端也可以关闭连接了。

B、为什么要等待2MSL

MSL:报文段最大生存时间,它是任何报文段被丢弃前在网络内的最长时间。
有以下两个原因:

  1. 第一点:保证TCP协议的全双工连接能够可靠关闭:
    由于IP协议的不可靠性或者是其它网络原因,导致了Server端没有收到Client端的ACK报文,那么Server端就会在超时之后重新发送FIN,如果此时Client端的连接已经关闭处于CLOESD状态,那么重发的FIN就找不到对应的连接了,从而导致连接错乱,所以,Client端发送完最后的ACK不能直接进入CLOSED状态,而要保持TIME_WAIT,当再次收到FIN的收,能够保证对方收到ACK,最后正确关闭连接。
  2. 第二点:保证这次连接的重复数据段从网络中消失
    如果Client端发送最后的ACK直接进入CLOSED状态,然后又再向Server端发起一个新连接,这时不能保证新连接的与刚关闭的连接的端口号是不同的,也就是新连接和老连接的端口号可能一样了,那么就可能出现问题:如果前一次的连接某些数据滞留在网络中,这些延迟数据在建立新连接后到达Client端,由于新老连接的端口号和IP都一样,TCP协议就认为延迟数据是属于新连接的,新连接就会接收到脏数据,这样就会导致数据包混乱。所以TCP连接需要在TIME_WAIT状态等待2倍MSL,才能保证本次连接的所有数据在网络中消失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值