TCP传输控制协议

时间:2021-07-12 10:18:01

一、 TCP协议

      TCP是一种面向连接(连接导向)的、可靠的基于字节流的传输层通信协议。TCP将用户数据打包成报文段,它发送后启动一个定时器,另一端收到的数据进行确认、对失序的数据重新排序、丢弃重复数据。

TCP的特点有:

1. TCP是面向连接的运输层协议

2. 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的

3. TCP提供可靠交付的服务

4. TCP提供全双工通信。数据在两个方向上独立的进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号。

5. 面向字节流。面向字节流的含义:虽然应用程序和TCP交互是一次一个数据块,但TCP把应用程序交下来的数据仅仅是一连串的无结构的字节流

TCP报文首部,如下图所示:

TCP传输控制协议

1. 源端口号:数据发起者的端口号,16bit

2. 目的端口号:数据接收者的端口号,16bit

3. 序号:32bit的序列号,由发送方使用

4. 确认序号:32bit的确认号,是接收数据方期望收到发送方的下一个报文段的序号,因此确认序号应当是上次已成功收到数据字节序号加1。

5. 首部长度:首部中32bit字的数目,可表示15*32bit=60字节的首部。一般首部长度为20字节。

6. 保留:6bit, 均为0

7. 紧急URG:当URG=1时,表示报文段中有紧急数据,应尽快传送。

8. 确认比特ACK:ACK = 1时代表这是一个确认的TCP包,取值0则不是确认包。

9. 推送比特PSH:当发送端PSH=1时,接收端尽快的交付给应用进程。

10. 复位比特(RST):当RST=1时,表明TCP连接中出现严重差错,必须释放连接,再重新建立连接。

11. 同步比特SYN:在建立连接是用来同步序号。SYN=1, ACK=0表示一个连接请求报文段。SYN=1,ACK=1表示同意建立连接。

12. 终止比特FIN:FIN=1时,表明此报文段的发送端的数据已经发送完毕,并要求释放传输连接。

13. 窗口:用来控制对方发送的数据量,通知发放已确定的发送窗口上限。

14. 检验和:该字段检验的范围包括首部和数据这两部分。由发端计算和存储,并由收端进行验证。

15. 紧急指针:紧急指针在URG=1时才有效,它指出本报文段中的紧急数据的字节数。

16. 选项:长度可变,最长可达40字节

注意:URG紧急指针和PSH推送的区别

1)URG紧急位

URG标志URG紧急指针有效。当URG=1时,表示分段中有紧急数据应当加速传送。其中的紧急数据需要直接交付给接收端的进程,而不进入缓存。

    紧急数据的长度=紧急指针;

    紧急数据的起始点=序号;

    紧急数据的终止点=序号+紧急指针;

(综上,紧急指针就是记录紧急数据的字节数,紧急指针永远为正数)

   i)在紧急数据后面的数据为普通数据,需要按序缓存

   ii)窗口为0也可以发送紧急数据

   iii)紧急数据都处理完成后,tcp就告诉进程恢复到正常操作

2) PSH推送位

     PPSH标志 PSH 紧急位。当PSH=1时,要求发送方马上发送该分段,将这个报文及缓存区之间缓存尚未交付的数据一并交付给进程,不做队列处理。

     1)PSH的数据=本报文数据+缓存区数据

     2)PSH的方向--->单方向(接收PSH报文的一端)     

3) 区别

    URG交付给进程的数据:只有紧急数据,而且不经过缓冲区

    PSH交付给进程的数据:缓冲区排好序的数据及当前报文中的数据,经过缓冲区


二、 TCP连接

其实,网络上的传输是没有连接的,包括TCP也是一样的。而TCP所谓的“连接”,其实只不过是在通讯的双方维护一个“连接状态”,让它看上去好像有连接一样。所以,TCP的状态变换是非常重要的。

下面是:“TCP协议的状态机”(图片来源) 和 “TCP建链接”、“TCP断链接”、“传数据” 的对照图

TCP传输控制协议 TCP传输控制协议

接下来是一个具体的例子。

TCP传输控制协议

建立连接

首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了。

附:

我们看到在client发送请求的时候,mss值为1460?这个值是怎么来的呢?

首先数据在传输的时候需要经过数据链路层(MAC)、网络层(IP)、传输层(TCP),我们知道一般在数据链路层采用的是以太网,而以太网的MTU(最大传输单元)为1500字节,IP数据报的报文长度最少为20字节,TCP的报文长度最少为20,所以最多能传送的数据的个数就是1460.


断开连接

【注意】中断连接端可以是Client端,也可以是Server端。

假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!(这也是为什么需要四次挥手的原因)

整个过程Client端所经历的状态如下:

TCP传输控制协议

而Server端所经历的过程如下:

TCP传输控制协议



为什么TCP建立连接的时候是三次,两次不可以吗,四次呢?

在只有两次握手的情况下:假设client请求和server建立连接,server收到了client的请求,并且发送了一个应答信号,并且开辟了资源,但是client由于某种原因可能没有收到应答信号。此时client就会继续重新发送连接请求,导致server会建立两次连接响应,开辟两次资源。一旦出现了多次的client收不到server的应答请求,那么就会造成server端资源的严重浪费,而且还会占用带宽。

所以再添加一次client的确认信号,来保证刚刚的两次连接是已经建立成功的,能够保证通信。三次就已经能保证当前的通信为全双工。至于为何没有第四次,因为通过三次握手双方已经互相确保了己方、对方都可以正常接收、发送信息了,无需第四次。