TCP协议

说起TCP三次握手,四次挥手,是面试的常客。TCP(Transmission Control Protocol),传输控制协议,是ISO模型中传输层的协议,有着控制IP层数据包传输的可靠性,记录两端传输端口号等作用。

wireshark抓取iphone wireshark抓取tcp三次握手_tcp/ip

WireShark工具

WireShark是一个抓包工具,可以对网卡上的网络请求进行抓取分析。可以看到每层协议的数据报文,如图。

wireshark抓取iphone wireshark抓取tcp三次握手_wireshark_02

三次握手

言归正传,为了建立可靠的连接,TCP采用三次握手的方法。


客户端 服务器 请求连接,SYN 我收到了,我也要连接你,SYN,ACK 好的,ACK 客户端 服务器


如图:

wireshark抓取iphone wireshark抓取tcp三次握手_服务器_03

第一条报文(发完之后,请求发进入SYN_SEND状态,等待服务器确认):

wireshark抓取iphone wireshark抓取tcp三次握手_tcp/ip_04


红框从上往下看:

  • 1、网络层IP协议的报文,我们可以看到Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1,发起和目的地都是127.0.0.1,因为我是本地模拟的
  • 2、在传输层TCP协议中,可以看到
    指定了客户端与响应方的端口号,这里的62884是我浏览器的端口号,80是服务器nginx的端口号
  • 3、Sequence number: 0 ,报文的序列号,每个报文会分配一个seq。
  • 4、Next sequence number: 1 ,我下一个将要发送的序列号是1,你注意按序查收。
  • 5、Acknowledgment number: 0,你确认的报文序列号请以seq=0发给我,这样我知道是你发的
  • 6、 … … …1. = Syn: Set,在标记位的Syn为1,其余为0,表明只是一条请求建立连接的报文
  • 7、Window size value: 8192,滑动窗口大小,在不同的网络环境下会自动调节。
第二条报文(ACK为第一条报文的seq+1,发完服务器进入SYN_RECV状态,等待客户端确认):

wireshark抓取iphone wireshark抓取tcp三次握手_tcp/ip_05

这是第二次握手的报文,

  • 1、下一个报文序列号为1
  • 2、序列号1以前的报文我都确认了,你可以往下发
  • 3、这条报文的flags标志位就是ack+syn

从第二条我们知道,下一次seq=1

第三条报文(客户端向服务器确认已收到,并进入ESTABLISHED状态,服务器收到确认,也进入ESTABLISHED状态,连接建立):

wireshark抓取iphone wireshark抓取tcp三次握手_服务器_06

  • 1、序列号为1,(0号报文已经被确认了,所以要下一个序列号)
  • 2、我发你的下一条报文也是1.(序列号的生成暂时还不是很清楚,不过每次前一条报文告诉对方我下一次要发的报文seq,就能按顺序接收。这里因为是在建立连接,可以复用这个序列号
  • 3、flags表明这是一条确认报文。
四次挥手

wireshark抓取iphone wireshark抓取tcp三次握手_tcp/ip_07


我们在应用中比较常用的网络协议就是HTTP协议了,在连接在一段时间内没有数据传输时,服务器就会请求断开。(否则过多的连接却不断开服务器肯定会受不了)

但HTTP一般是基于TCP协议的,TCP是传输控制协议,需要确保传输的可靠的,数据是不丢失的,这就引出了四次挥手。

下面的客户端和服务器可以互换,任意一方都可以发起断开。

服务器 客户端 请求断开连接,你能断开了吗,(FIN,ACK) 我收到了,我好了我和你说,ACK 我可以断开了,你现在可以吗,(FIN,ACK) 可以断开了(ACK) 服务器 客户端


第一次挥手(服务端发起FIN+ACK报文,发完进入FIN_WAIT_1状态)

wireshark抓取iphone wireshark抓取tcp三次握手_tcp/ip_08

第二次挥手(客户端确认,返回ACK报文,ACK=前一条Seq+1。发完服务器就进入第二段等待状态FIN_WAIT_2,等待客户端的FIN、ACK报文)

wireshark抓取iphone wireshark抓取tcp三次握手_tcp/ip_09


这里的seq和next seq也是复用的,都是577

第三次挥手(客户端发送FIN+ACK告诉服务器我可以断开了,进入等待关闭状态CLOSE_WAIT)

wireshark抓取iphone wireshark抓取tcp三次握手_面试_10

第四次挥手(服务器收到FIN+ACK,便发送确认报文,进入定时等待TIME_WAIT,客户端收到后,就closed。服务器会TIME_WAIT状态等待2MSL时间,如果没收到回复,就直接关闭)

wireshark抓取iphone wireshark抓取tcp三次握手_面试_11

拓展
什么是MSL

MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为tcp报文(segment)是ip数据报(datagram)的数据部分,具体称谓请参见《数据在网络各层中的称呼》一文,而ip头中有一个TTL域,TTL是time to live的缩写,中文可以译为“生存时间”,这个生存时间是由源主机设置初始值但不是存的具体时间,而是存储了一个ip数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报文通知源主机。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。

2MSL即两倍的MSL,TCP的TIME_WAIT状态也称为2MSL等待状态,当TCP的一端发起主动关闭,在发出最后一个ACK包后,即第3次握手完成后发送了第四次握手的ACK包后就进入了TIME_WAIT状态,必须在此状态上停留两倍的MSL时间,等待2MSL时间主要目的是怕最后一个ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。不过在实际应用中可以通过设置SO_REUSEADDR选项达到不必等待2MSL时间结束再使用此端口。

总结:

学习TCP协议三次握手,四次挥手是认识TCP可靠传输的重要的一部分,还有拥塞控制,滑动窗口的概念之后也会讲。