TCP协议个人记录

TCP

TCP协议学了不知道多久了,但是对于三次握手,四次挥手什么的,都只是字面上记住了,没个实感觉,今天用wirewark抓包看了看感觉印象深刻了不少

TCP报文简介

TCP报文简介

一些字段说明

  • 序号(sequence number):Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记
    • ISN也就是Init Sequence Number
  • 确认号(acknowledgement number):Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1,注意这里Ack和下面flags的ACK的区别
  • 标志位(Flags):共6个,即URG、ACK、PSH、RST、SYN、FIN等
    • URG:紧急指针(urgent pointer)有效
    • ACK:确认序号有效,在TCP通信过程中只有第一个报文没有ACK
    • PSH:接收方应该尽快将这个报文交给应用层
    • RST:重置连接
    • SYN:发起一个新连接,一般在握手过程出现
    • FIN:释放一个连接

注意:

sequence number:表示的是我方(发送方)这边,这个packet的数据部分的第一位应该在整个data stream中所在的位置。(注意这里使用的是“应该”。因为对于没有数据的传输,如ACK,虽然它有一个seq,但是这次传输在整个data stream中是不占位置的。所以下一个实际有数据的传输,会依旧从上一次发送ACK的数据包的seq开始)

acknowledge number:表示的是期望的对方(接收方)的下一次sequence number是多少。

SYN/FIN的传输虽然没有data,但是会让下一次传输的packet seq增加一,但是,ACK的传输,不会让下一次的传输packet加一。

三次握手示意图

TCP三次握手

抓包显示

wireshark三次握手

第一次握手:客户点(端口号49980)向服务器端(端口号443)发送第一次握手请求,此时SYN=1,表示“请求建立新连接”,seq=j=0,ACK=0

第二次握手:服务器端收到后,向客户端发送第二次握手请求,[SYN, ACK],表示“确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接”,其中Seq=k=0,Ack=j+1=1

第三次握手,客户端向服务器发一个[ACK],其中Seq=j+1=1(上一个包序号是j,当前这个包为j+1),Ack=k+1=1

握手完成,建立连接,开始数据传输

通信过程

三次握手是3个包,通信过程每次2个包,挥手是4个包,通信过程的两个包是发送消息1个包,对方没有消息,只有确认ACK

下面是转载自TCP协议中的seq/ack序号是如何变化的?的TCP通信过程

TCP通信过程

可以看到,前三条是建立连接的过程,后续是TCP发送数据的过程,每次发送成对出现,接收方返回的只有确认ACK,这与wireshark抓包结果对应

抓包通信过程

并且这里可以看出,接收方返回的Ack=发送方发送的Seq,发送方收到后,下一次发送的Seq不是等于接收方的Ack+1,而是Ack+len(这里的len是发送方发送的len),而在一些软件抓包结果中(比如上图),接受不了方返回的Ack等于发送方的Seq+len,其实效果是一样的

抓包通信过程1

一次重传过程

一次重传过程

这里可以看到第329条发送过去后,本应该收到334条的Ack为19073,却是20525,与发送的不一致,故在325条进行了重传

四次挥手

TCP四次挥手

四次挥手要注意等待状态的变化,主动断开方发送FIN=1时,处于FIN-WAIT-1状态,当其收到被动断开方的ACK后,处于FIN-WAIT-2

为什么A(主动断开方)在TIME-WAIT状态必须等待2MSL的时间?

  • 这个ACK报文段有可能丢失,使得处于LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认,B超时重传FIN+ACK报文段,而A能在2MSL时间内收到这个重传的FIN+ACK报文段,接着A重传一次确认,重新启动2MSL计时器,最后A和B都进入到CLOSED状态,若A在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到B重传的FIN+ACK报文段,所以不会再发送一次确认报文段,则B无法正常进入到CLOSED状态
  • A在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段
  • 上面只是一个原因。第二个原因是处理延迟的重复报文,这主要是为了避免前后两个使用相同四元组的连接中的前一个连接的报文干扰后一个连接。这一点是因为被动关闭端未接收到ACK时,会不停的发FIN,而第二个这个 FIN 最坏会在 1MSL 时间内消失
  • 总结便是假如现在 A 发送 ACK 后,最坏情况下,这个 ACK 在 1MSL 时到达 B;此时 B 在收到这个 ACK 的前一刹那,一直在重传 FIN,这个 FIN 最坏会在 1MSL 时间内消失。因此从 A 发送 ACK 的那一刹那开始,等待 2MSL 可以保证 A 发送的最后一个 ACK,和 B 发送的最后一个 FIN 都在网络中消失

为什么会四次挥手?

  • 收到发送方的FIN后,这时对方会回一个ACK,此时一个方向的连接关闭。但是另一个方向仍然可以继续传输数据,也就是说,服务端收到客户端的 FIN 标志,知道客户端想要断开这次连接了,但是,我服务端,我还想发数据呢?我等到发送完了所有的数据后,会发送一个 FIN 段来关闭此方向上的连接。接收方发送 ACK确认关闭连接

  • 注意,接收到FIN报文的一方只能回复一个ACK, 它是无法马上返回对方一个FIN报文段的,因为结束数据传输的“指令”是上层应用层给出的,我只是一个“搬运工”,我无法了解“上层的意志”

wireshark抓包示意图

四次挥手

HTTP与TCP的关系

图片来源wuxinliulei

v2-de748d66e75881431505e735b292a83b_1440w

Http的首部就是上图中的Appl首部,一条Http请求或者响应协议会被分成N个TCP协议报文,每个TCP报文又被IP报文封装(也就是说TCP报文被分拆到ip报文的数据中),http协议,tcp报文和ip报文头部的内容是不同的,比如IP报文头部由源IP和目的IP信息,TCP报文头部有源端口号和目的端口号信息等

TCP的拥塞控制

待补充

面试常问问题

涉及网络编程源码的东西,time_wait之类的

为什么2次连接不行

“三次握手” 的目的是 “为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。

已失效的连接请求报文段” 的产生在这样一种情况下:client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采用 “三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用 “三次握手” 的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。

三次握手过程中可以携带数据吗?

第一次不可以,那会儿连接还没建立,第三次可以。如果第一次可以的话,会导致SYN flood攻击。

ISN(Initial Sequence Number)是固定的吗?

不是,是随时间动态随机生成的。如果 ISN 是固定的,攻击者很容易猜出后续的确认号。

对于连接的3次握手,主要是要初始化Sequence Number 的初始值。通信的双方要互相通知对方自己的初始化的Sequence Number(缩写为ISN:Inital Sequence Number)。这个号要作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上的传输的问题而乱序(TCP会用这个序号来拼接数据)。

最后一次挥手有什么用

连接释放的时候,实际上是其中一方,如A提出了释放请求,B收到后进行了报文确认,那么A到B的连接就释放了,这个时候,B还是可以向A发送数据,而且A会直接接收,到了B数据发送完了,B再向A发送请求释放的请求,B进入超时等待阶段,如果A及时发送连接中断确认,那么B就释放了B到A的连接,如果没有收到,超过一段时间,自动释放。

TCP的窗口大小

TCP通过滑动窗口的概念来进行流量控制。设想在发送端发送数据的速度很快而接收端接收速度却很慢的情况下,为了保证数据不丢失,显然需要进行流量控制, 协调好通信双方的工作节奏。

滑动窗口本质上是描述接受方的TCP数据报缓冲区大小的数据。

转载来源和参考:

面试官,不要再问我三次握手和四次挥手

详解 TCP 连接的“ 三次握手 ”与“ 四次挥手 ”

详解TCP建立连接、传输数据、断开连接全过程

TCP协议中的seq/ack序号是如何变化的?非常棒的过程分析!

简述TCP建立连接和释放连接

一文搞定 UDP 和 TCP 高频面试题!

Hellow woooo的博客记录

Gypsophila N的知乎回答