网络协议之传输层协议TCP

2019-10-29  本文已影响0人  初心myp

首先我们应该深刻理解网络4/7层模型,然后一起学习传输层的TCP

两个非常重要的网络协议:HTTP、TCP。这两个协议也是服务交互中使用最多的协议。

TCP协议特点

TCP是传输层协议,对应OSI网络模型的第四层传输层,特点如下:

除了TCP协议的特点,还可以进一步了解TCP协议的报文状态、滑动窗口的工作流程、keepalive的参数设置和Nagel算法的规则等一些细节。

另外还有典型的TCP协议问题,例如特定场景下Nagel和ACK延迟机制配合使用可能会出现delay40ms超时后才回复ACK包问题。

聊一聊TCP的三次握手建连和四次挥手断连

1. 详解三次握手建连

接下来看TCP建连的三次握手。TCP是基于链接的,所以在传输数据前需要先建立链接,TCP在传输上是双向传输,不区分Client和Server端,为了便于理解,我们把主动发起建连请求一端称为Client端,把被动建连的一段称为Server端。
如下图所示,建连的时序从上到下,左右两边的绿色分别代表Client和Server端当时的链接状态。

image.png

首先建立链接前需要Server端先监听端口,因此Server端建立链接前的初始状态是LISTEN状态,这是Client端准备建立链接,先发送一个SYN同步包,发送完同步包后,Client端的链接状态变成了SYN_SENT状态。Server端收到SYN后,同意建立链接,会向Client端回复一个ACK。

由于TCP是双向传输,Server端也会向Client端发送一个SYN,申请Server向Client方向建立链接,发送完SYN和ACK后,Server端就变成了SYN_RCVD。

Client收到Server的ACK后,Client状态就变成了ESTABLISHED,同时,Client向Server端发送ACK,回复Server端的SYN请求。

Server端收到Client端ACK后,Server端状态也变成ESTABLISHED状态,此时建连完成,双方随时可以进行数据传输。

如果面试的时候,我们需要明白三次握手为了建立双向链接,需要记住Client端和Server端的链接状态变化。另外回答建连的问题时,可以提到SYN洪水攻击发生的原因,就是Server端接收到Client端的SYN请求后,发送了SYN和ACK,但是Client端不进行回复,导致Server端大量的链接处在SYN_RCVD状态,进而影响其它正常请求建连。可以设置tcp_synack_retries = 0加快半链接的回收速度,或者调大tcp_max_syn_backlog来应对少量的SYN洪水攻击

2. 详解四次挥手断连

接下来看一看,TCP断连,如下图:

image.png

TCP链接的关闭,双方都可以先发起,我们暂时把先发起的一端称为Client端,,从图上可以看出,通信中的Client和Server都处于ESTABLISHED状态,然后Client先主动发起了关闭链接请求,Client向Server发送一个FIN包,表示Client端已经没有数据要发送了,然后Client进入了FIN_WAIT_1状态。

Server端收到FIN后,返回ACK,然后进入CLOSE_WAIT状态。此时Server属于半关闭状态,因为此时Client已经不会向Server发送数据了,但是Server端可能还有数据要向Client发送。

当Server发送完毕后,Server端会向Client端发送FIN,表示Server端也没有数据需要发送了,此时Server进入LAST_ACK状态,就等待Client应答就可以关闭链接了。

Client端收到Server端的FIN后,回复ACK,然后进入TIME_WAIT状态。TIME_WAIT状态下需要等待2倍的最大报文段生存时间,来保证链接可靠关闭,之后才会进入CLOSED关闭状态。而Server端接收到ACK后会直接进入CLOSED状态。

这里有一个面试的知识点,面试官可能在这里问为什么需要等待2倍的最大报文段生存时间之后再关闭链接,原因有两个:

  1. 保证TCP协议的全双工链接能够可靠关闭
  2. 保证这次连接的重复数据段在网络中消失,防止端口被重用是可能造成数据混淆。

从上面的交互流程上可以看出,无论是建连还是断连,都是需要两个方向上进行的,只不过建连时,Server端的SYN和ACK合并为一次发送了,断连时两个方向上数据发送停止时间可能不同,所以不能合并发送FIN和ACK,这就是建连需要三次握手,而断连需要四次挥手的原因了

另外回答断连的问题时,可以提到实际应用中可能遇到大量Socket处在TIME_WIT或者CLOSE_WAIT状态的问题。一般开启tcp_tw_reuse和tcp_tw_recycle能过加快TIME_WAIT的Sockets回收;而大量CLOSE_WAIT可能是被动关闭的一方存在代码bug,没有正确关闭链接导致的。

上一篇 下一篇

猜你喜欢

热点阅读