这个题非常有意思。哈哈。
首先,基于tcp来的嘛,在这种一次通信的过程中,大概需要一些步骤,例如tcp的三次握手和四次挥手。
那么,三次和四次的区别就是有一个不用传数据,不用等1次往返时间,节约了带宽。
那么,SYN主要用于连接的确认,FIN主要用于一方放弃连接的初始化确认,RET代表什么?
这是这道题的关键。
linux内核一般来说会有很多时间去进行兜底,来确保一次连接的一个最大存活时间。
在ubuntu18.04上,一次tcp连接的最大存活时间是好几天,而每次双方发起的连接都会进行一个ACK的确认。这个确认信息非常关键,这个确认收到之前还是这次链接,没有断开。那么ubuntu18.04呢,这个确认时间是5分钟。
那么,当某一方突然挂机,另一方是无法知道对方挂机的,因为对方又没给自己FIN断开,自己如果没有主动联系对方,那么这个连接就一直保持,直到操作系统的那个时间兜底来临。
再说一次,操作系统的那个兜底时间其实也好说,因为那个时间在每次有新的TCP活动来临都会刷新。而后者ACK主要是在ACK来临时会主动刷新。因为TCP链接很昂贵,所以提出了keep-alive这个字段来尽可能将多次请求在一次连接复用,当也不能当神药去一直复用。
keep-alive就可以设置超时时间,这是应用层的超时时间,是由应用层控制的时间,优先级权重大于下层。
所以在B挂机重启的一端时间内,A还一位这个连接保持,所以它会一直存在,知道B重启自然进入到listen状态,这个时候,B是不知道自己和A之前还有连接的。
此时能够改变现状的只有A,A主动发任何的消息给B,B察觉这次通信是异常的,会要求重置连接,因此发送RST给A,A收到之后会重置自己该tcp连接的各种时间。然后A就处于向内核发送消息的这么一个状态临界,自然会进入到SYN_SEND状态。