TCP

265 阅读10分钟

TCP

TCP协议的特点

在不可靠的IP层上实现的可靠的数据传输协议

主要解决传输的可靠、有序、无丢失和不重复的问题

面向字节流的

TCP报文的长度根据接收方给出的窗口值(流量控制)和当前网络阻塞程度来决定

TCP报文段

TCP传送的数据单元称为报文段,TCP报文段既可以用来运载数据,又可以用来建立连接、释放连接和应答

一个TCP报文段分为首部和数据两部分

首部的前20B是固定的。TCP报文段的首部最短为20B,后面有4N字节是根据需要而增加的选项,通常长度为4B的整数倍。

  • 1)源端口和目的端口字段。各占2B。端口是运输层与应用层的服务接口,运输层的复用和分用功能都要通过端口实现。
  • 2)序号字段(seq)。占4B。TCP是面向字节流的(即TCP传送时是逐个字节传送的),所以TCP连接传送的数据流中的每个字节都编上一个序号。序号字段的值指的是本报文段所发送的数据的第一个字节的序号。序号字段由TCP服务器进程随意指定(不同的TCP进程的seq无联系)
  • 3)确认号字段。占4B,是期望收到对方的下一个报文段的数据的第一个字节的序号。若确认号为N,则表明到序号N- 1为止的所有数据都已正确收到。
  • 4)数据偏移(即首部长度)占4位,这里不是IP数据报分片的那个数据偏移,而是表示首部长度,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。“数据偏移”的单位是32位(以4B为计算单位)。因此当此字段的值为15时,达到TCP首部的最大长度60B.
  • 5)保留字段。占6位,保留为今后使用,但目前应置为0,该字段可以忽略不计。
  • 6)紧急位URG。URG= 1时,表明紧急指针字段有效。它告诉系统报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。但URG需要和紧急指针配套使用,即数据从第一个字节到紧急指针所指字节就是紧急数据。
  • 7)确认位ACK。只有当ACK= 1时确认号字段才有效。当ACK=0时,确认号无效。TCP规定,在连接建立后所有传送的报文段都必须把ACK置1.
  • 8)推送位PSH (Push)。 接收TCP收到PSH= 1的报文段,就尽快地交付给接收应用进程而不再等到整个缓存都填满后再向上交付。
  • 9)复位位RST (Reset)。RST=1时,表明TCP连接中出现严重差错(如主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。
  • 10)同步位SYN同步SYN= 1表示这是一个连接请求或连接接收报文(不携带数据,但消耗一个序号)当SYN=1, ACK=0时,表明这是一个连接请求报文对方若同意建立连接,则在响应报文中使用SYN=1, ACK=1。即SYN= 1表示这是一个连接请求或连接接收报文。
  • 11)终止位FIN (Finish)。用来释放一个连接。FIN= 1(不携带数据,但消耗一个序号)表明此报文段的发送方的数据已发送完毕,并要求释放传输连接
  • 12)窗口字段。占2B。它指出现在允许对方发送的数据量,接收方的数据缓存空间是有限的,因此用窗口值作为接收方让发送方设置其发送窗口的依据,单位为字节。 例如,假设确认号是701,窗口字段是1000。这表明,从701号算起,发送此报文段的接收方方还有接收1000B数据(字节序号为701 ~1700)的接收缓存空间。
  • 13)校验和。占2B。校验和字段检验的范围包括首部和数据两部分。在计算校验和时,和UDP一样,要在TCP报文段的前面加上12B的伪首部(只需将UDP伪首部的第4个字段,即协议字段的17改成6,其他的和UDP一样)。
  • 14)紧急指针字段。占16 位,指出在本报文段中紧急数据共有多少字节(紧急数据放在本报文段数据的最前面)
  • 15)选项字段。长度可变。TCP最初只规定了一种选项,即最大报文段长度(Maximum SegmentSize,MSS)。MSS是TCP报文段中的数据字段的最大长度。窗口扩大、时间戳、选择确认
  • 16)填充字段。这是为了使整个首部长度是4B的整数倍。填充0.
TCP连接管理

TCP是面向连接的协议,因此每个TCP连接都有三个阶段:连接建立、数据传送和连接释放

TCP连接管理就是使运输连接的建立和释放都能正常进行

在TCP连接建立的过程中,要解决以下三个问题:

  • 1)要使每一方都能够确知对方的存在。
  • 2)要允许双方协商一些参数(如最大窗口值、是否使用窗口扩大选项、时间戳选项及服务质量等)。
  • 3)能够对运输实体资源( 如缓存大小、连接表中的项目等)进行分配。

每条TCP连接通过通信两端的两个端点( 即两个套接字)确定。

TCP连接的建立

连接的建立经历3个步骤,通常称为三次握手

连接建立前,TCP服务器进程处于LISTEN(收听)状态,等待客户的连接请求

客户是主动打开TCP连接,服务器是被动打开

  • 第一步:客户机的TCP首先向服务器的TCP发送一个连接请求报文段。这个特殊的报文段中不含应用层数据,其首部中的SYN标志位被置为1。另外,客户机会随机选择一个起始序号 seq= x(连接请求报文不携带数据,但要消耗一个序号)。
  • 第二步:服务器的TCP收到连接请求报文段后,如同意建立连接,就向客户机发回确认,并为该TCP连接分配TCP缓存和变量。在确认报文段中,SYN和ACK位都被置为1,确认号字段的值为x+ 1, 并且服务器随机产生起始序号seq = y(确认报文不携带数据,但也要消耗-一个序号)。确认报文段同样不包含应用层数据。
  • 第三步:当客户机收到确认报文段后,还要向服务器给出确认,并且也要给该连接分配缓存和变量。这个报文段的ACK标志位被置1,序号字段为x+1,确认号字段ack=y+ 1。该报文段可以携带数据,若不携带数据则不消耗序号。
  • 成功进行以上三步后,就建立了TCP连接,接下来就可以传送应用层数据。

TCP提供的是全双工通信,因此通信双方的应用进程在任何时候都能发送数据。

  • 服务器端的资源是在完成第二次握手时分配的
  • 而客户端的资源是在完成第三次握手时分配的,这就使得服务器易于受到SYN洪泛攻击。

为什么是3次握手?

使用三次握手和RST控制消息将是否建立连接的最终控制权交给了发送方,因为只有发送方有足够的上下文来判断当前连接是否是错误的或者过期的,这也是 TCP 使用三次握手建立连接的最主要原因。

TCP 建立连接时通过三次握手可以有效地避免历史错误连接的建立,减少通信双方不必要的资源消耗。

两次握手:无法避免历史错误连接的初始化,浪费接收方的资源; 四次握手:TCP 协议的设计可以让我们同时传递 ACK 和 SYN 两个控制信息,减少了通信次数,所以不需要使用更多的通信次数传输相同的信息。

TCP连接的释放

TCP连接释放的过程通常称为四次握手

  • 第一步:客户机打算关闭连接时,向其TCP发送一个连接释放报文段, 并停止发送数据,主动关闭TCP连接,

    该报文段的FIN标志位被置1, seq=u, 它等于前面已传送过的数据的最后一个字节的序号加1 (FIN报文段即使不携带数据,也要消耗一个序号)。 TCP 是全双工的,即可以想象为一条TCP连接上有两条数据通路。 发送FIN报文时,发送FIN的一端不能再发送数据,即关闭了其中一条数据通路,但对方还可以发送数据。

  • 第二步:服务器收到连接释放报文段后即发出确认,确认号是ack=u+ 1,而这个报文段自己的序号是v,等于它前面已传送过的数据的最后一个字节的序号加1。 此时,从客户机到服务器这个方向的连接就释放了,TCP连接处于半关闭状态。 但服务器若发送数据,客户机仍要接收,即从服务器到客户机这个方向的连接并未关闭。

  • 第三步:若服务器已经没有要向客户机发送的数据,就通知TCP释放连接,此时其发出FIN= 1,ACK=1的连接释放报文段

  • 第四步:客户机收到连接释放报文段后,必须发出确认。在确认报文段中,ACK字段被置为1,确认号ack=w+1,序号seq=u+1.此时TCP连接还未释放,必须经过时间等待计时器设置的时间2MSL后,A才进入连接关闭状态。

为什么A(客户端)在TIME-WAIT状态必须等待2MSL时间呢?

为了保证A发送的最后一个ACK报文能够到达B。这个ACK报文有可能丢失,因而使处于在LAST-ACK状态的B收不到A发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,A就能在2MSL时间内收到这个重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计数器。最后A和B都正常进入到CLOSED状态。如果A在TIME_WAIT状态不等一段时间而是在发送完ACK报文段后立即释放连接,那么就无法收到B重传的FIN+ACK报文段。B就无法按照正常步骤进入CLOSED状态

连接建立和释放总结

1)连接建立。分为3步: ①SYN=1,seq=x。 ②SYN=1, ACK=1, seq=y, ack=x+ 1。 ③ACK=1,seq=x+1, ack=y+ 1。 2)释放连接。分为4步: ①FIN=1, seq= u ②ACK=1, seq=v, ack=u+ 1。 ③FIN=1,ACK=1, seq=w,ack=u+ 1。 ④ACK=1, seq=u+1, ack=w+ 1。

待补充TCP可靠传输,拥塞控制等