运输层(三)TCP协议

前言:

来源于《计算机网络自顶向下方法》,终于来到了TCP协议,TCP协议也是面试中问的最多的知识点之一了。

面向连接的运输:tcp

  • tcp被称为是面向连接的。这是因为一个应用进程可以开始向另一个应用进程发送数据之前,这两个进程必须先相互握手。即他们必须相互发送某些预备报文,以建立确保数据传输的参数。作为tcp连接建立的一部分。连接双方都将初始化与tcp连接相关的许多tcp状态变量。
  • tcp连接是面向字节流的。TCP是有缓冲区,TCP发送报文时,是将应用层数据写入TCP缓冲区中,然后由TCP协议来控制发送这里面的数据,tcp可以从发送缓存中取出并放入报文段的数据数量受限于最大报文段长度(MMS)。MMS通常由本地发送主机发送的最大链路层帧长度,即所谓的最大传输单元MTU。设置该mms要保证一个tcp报文段加上tcp/ip首部长度将适合单个链路层帧。(因为ip层是不可靠的,这样子丢包的话也是一整个tcp包丢掉,而不是丢掉tcp包的一部分。方便后面的检测并且重传。) MMS是指在报文段里应用层数据的最大长度。不包含首部的tcp报文长度。
  • tcp提供可靠交付的服务。通过TCP连接传送的数据,无差错、不丢失、不重复、 并且按序到达
  • tcp连接提供的是双工服务,应用层的数据可以从进程a流入进程b,也可以从进程b流入进程a
  • tcp连接是点对点的。即单个发送方与单个连接方之间的连接。
    面向报文(UDP)和面向字节流(TCP)的区别

tpc协议的运作图

在这里插入图片描述

tcp的报文结构在这里插入图片描述

由于书上的图拍出来不够清晰,这里找了张网图。
TCP报文段由首部字段和一个数据字段组成。数据字段包含一块应用数据。如上部分介绍tcp是面向字节流的协议,MSS限制了报文段数据字段的最大长度,当tcp发送一个大文件的时候,tcp通常是将该文件划分为长度mss的若干款,然后传输。

TCP报文段首部字段:
  • 源端口号和目的端口号:与udp一样,被用于多路复用以及多路分解
  • 检验和字段:提供了差错检测功能
  • 32bit的序号字段(sequence window field----seq)和32bit的确认号字段(acknowledgement number field—ack)。这些字段被tcp发送方和接收方用于实现可靠数据传输服务,三次四次握手。
  • 16bit的接收窗口字段:该字段用于流量控制,
  • 4bit的首部长度字段:该字段指示了以32bit的字为单位的tcp首部长度。由于tcp选项字段的原因,tcp首部的长度是可变的,通常,选项字段为空,所以一般tcp首部的典型长度为20bit(接收窗口+首部长度)
  • 可选和变长的选项字段:该字段用于发送方与接收方协商最大报文段MSS时或者在高速网络环境下用在窗口调节因子时使用
  • 6bit的标志字段: ACK bit用于确认字段中的值是有效的,即该报文包括一个对已成功接收报文的确定。RST、SYN和FIN用于连接建立和拆除。在明确拥塞通告中使用到了CWR ECE.当PSH被置位时,就指示接收方应立即将数据交给上层。URG用来指示报文段中存在着被发送端上层实体设置为紧急的数据,紧急数据的最后一个字节由16bit的紧急数据指针字段指出

序号和确认号

序号

tcp把数据看成是一个无结构、有序的字节流。序号是建立在传送的字节流之上的,而不是建立在传送的报文段序列之上的。一个报文段的序号应该是该报文段首字节的字节流编号。
如下图所示,第一个报文段的序号是0,第二个报文段的序号是1000,第三个报文段的序号就是2000ß
在这里插入图片描述

确认号

其实本质就是将接收报文中的序列号加1,即是确认号,用于表明之前传输的数据已经接收好了,并且等待下一个字节。
假如传输的0-500,500-1000两个报文段,接收方只收到了500-100的报文段,没有收到0-500报文段,接收方为了重新构建,则回传的确认号则一直是上一个序列号。表明需要0-500的报文段。这也就是累积确认。保证该流中至第一个丢失字节为止的字节都是完整的。

流量控制

阅读此博客即可。
https://blog.csdn.net/qq_22238021/article/details/80332750

了解握手之前我们先了解之前的标志字段,后面会用到

  • ACK : TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1

  • SYN(SYNchronization) : 在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1. 因此, SYN置1就表示这是一个连接请求或连接接受报文。

  • FIN (finis)即完,终结的意思, 用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。

TCP三次握手

在这里插入图片描述

  • 第一次握手:建立连接时,客户端发送SYN报文段到服务器,SYN=1 ACK=0,并进入SYN_SENT状态,等待服务器确认;该SYN报文段不包含应用层数据。客户端会随机选择初始序号seq=x,将其放到SYN报文段的序号字段中。该报文段被封装在一个IP数据报中并发送给服务器。SYN:同步序列编号(Synchronize Sequence Numbers)。

  • 第二次握手:服务器收到包含SYN报文段的IP数据报,服务器从数据报中提取SYN报文段,并为该TCP连接分配TCP缓存和变量,并向客户端发送允许连接的报文段:SYNACK报文段。该报文段不包含应用层数据。服务器选择自己的初始序号y放入该报文段首部的序号字段中。SYN=1,ACK=1,seq=y,确认号字段ack=x+1。此时服务器进入SYN_RECV状态;(后面为了放置syn攻击采用cookie机制,即先不为tcp连接分配tcp缓存和变量,完成三次握手后再分配)

  • 第三次握手:客户端收到服务器的SYNACK报文段后,客户也要为该连接分配缓存和变量。客户向服务器发送确认ACK=1,置ack=y+1,因连接已建立,故SYN=0。seq=x+1。此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。该确认报文段可以携带客户到服务器的数据。

其实本质上3次握手就是为了让双方都清楚对方的初始化序列号,并且确认对方都清楚。并且初始化tcp缓存和变量

TCP四次握手

在这里插入图片描述
由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。

  • 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
  • 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
  • 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
  • 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手

参考:
《计算机网络自顶向下》
https://blog.csdn.net/qq_22238021/article/details/80333279

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章