TCP 常见问题

记录tcp中常见的问题和答案。

FIN(半关闭)

FIN是终止一个方向的连接请求,因此,需要连接双方均终止各自方向的连接请求。

那为什么不能和三次握手一样,FIN+ACK同时传输?

TCP存在半关闭状态,也就是存在没有关闭的一端。

在TCP的双工通信中,假如一端完成了通信发起关闭,但是另外一端仍然有数据没有处理完,

此时会仅返回一个AKC,在处理完数据后才后发起FIN,到此,来算是另外一端关闭的开始

TIME_WAIT

TIME_WAIT状态也称为2MSL(最大报文段最大生存时间)等待状态·`。

注意:处于TIME_WAIT状态的端口是不能被使用。

主动断开TCP服务的一方会进入TIME_WAIT状态,此时端口无法使用。

为什么需要TIME_WAIT?

在主动关闭一方接收到被动关闭方发送的FIN后,回应ACK并进入TIME_WAIT状态。

TIME_WAIT状态是为了提高不可靠的网络中通信的可靠性

① 由于网络的不可靠,主动关闭回应的ACK可能会产生延迟
② 极端情况下,会触发被动一方重传FIN,重传的往返时间就是2MSL。

解决大量TIME_WAIT?

可配置参数,具体内容google:

  • ip_contrack
  • tcp_tw_recycle 回收
  • tcp_tw_reuse 复用
  • tcp_max_tw_buckets 总数设置

CLOSE_WAIT

CLOSE_WAIT状态是被动关闭方回应ACK之后的状态,也是在发送FIN给主动关闭方之前的状态。

处于CLOSE_WAIT状态的一端会在处理完本地数据(待发送)后转换为LAST ACK状态

一般来所CLOSE_WAIT的持续时间较长,至少为2小时,该端口将一直被占用。

出现CLOSE_WAIT的原因?

可能是在关闭连接之前有许多数据需要发送,也就是说被动关闭方自身存在问题

解决CLOSE_WAIT?

需要在业务层面判断连接是否已被对端关闭。

三次握手和四次握手的原因

单向握手

TCP建立连接时,客户端主动连接,服务器被动连接,因此,可以复用第二次握手来传递SYN/ACK,

双向挥手

TCP断开连接时,断开连接的顺序不是固定的,客户端和服务器都有可能主动断开连接(同时断开连接),所以不可以复用握手。

双向握手

双向握手也会产生四次握手。

TCP建立连接时,两端同时主动打开发送SYN,那么两端接收后会变为SYN_RCVD状态,再分别发送SYN、ACK进行确认(仅会建立一条通道,但拆分了SYN+ACK)。

请求不存在端口

当一个数据报到达目的端口时,如果该端口未被使用,

  • UDP返回ICMP不可达信息
  • TCP使用复位

Half-Open

半打开连接是指一方关闭连接或异常终止连接而另外一方却不知情的情况。
只要不打算在半打开连接上传输数据,仍处于连接状态的一方就不会检测另一方的异常状态。

backlog

socket listen参数中的backlog,是指TCP呼入连接请求队列的长度。

请求队列是用来存储那些三次握手连接,但并没有被应用层接受的连接,如果请求队列满了,TCP不会对SYN做出反应,从而迫使客户端TCP重传。