三次握手四次断开:
    image.png
    image.png

    连接建立超时:
    有很多情况导致无法建立连接。一种情况是服务器主机没有处于正常状态
    客户间隔多长时间发送一个SYN,试图建立连接。第2个SYN与第1个的间隔是5.8秒,而第3个与第2个的间隔是24秒。

    最大报文长度(MSS):(MTU - 40 )
    最大报文段长度(MSS)表示TCP传往另一端的最大块数据的长度。当一个连接建立时,连接的双方都要通告各自的MSS。
    IP数据报头通常是40字节长:20字节的TCP首部和20字节的IP首部。

    一般说来,如果没有分段发生,MSS还是越大越好:
    报文段越大允许每个报文段传送的数据就越多,相对IP和TCP首部有更高的网络利用率
    当TCP发送一个SYN时,或者是因为一个本地应用进程想发起一个连接,或者是因为另一端的主机收到了一个连接请求,
    它能将MSS值设置为外出接口上的MTU长度减去固定的IP首部和TCP首部长度。对于一个以太网,MSS值可达1460字节。(1500-20-20=1460)

    发送接收两端的MTU不一致时,MSS也会不一致(MSS = MTU - 40(IP首部和TCP首部长度)),为了避免MSS较小一方的数据分段
    这时会以最小的MSS来传输数据。

    TCP 的状态变迁:
    1. 2MSL等待状态(TIME_WAIT)
    TIME_WAIT状态也称为2MSL等待状态。
    MSL( Maximum Segment Lifetime ):报文段最大生存时间。
    RFC 793 [Postel 1981c]指出MSL为2分钟。然而,实现中的常用值是30秒,1分钟,或2分钟。
    对IP数据报TTL的限制是基于跳数,而不是定时器。
    TCP连接在2MSL等待期间,客户的IP地址和端口号,服务器的IP地址和端口号不能再被使用。

    2. 平静时间的概念
    RFC 793指出TCP在重启动后的MSL秒内不能建立任何连接。这就称为平静时间(quiet time)
    只有极少的实现版遵守这一原则,因为大多数主机重启动的时间都比MSL秒要长。

    3. FIN_WAIT_2状态
    客户端已经发送了 FIN,并且服务器端已经返回确认,这时候客户端就会保持 FIN_WAIT_2 状态。只有当服务器端进程关闭这个连接的时候,
    客户端才会进入TIME_WAIT状态。否则客户端会一直保持 FIN_WAIT_2 状态,而服务器端一直保持 CLOSE_WAIT 状态。

    复位报文段(RST)
    RST比特是用于“复位”的。
    一般说来,无论何时一个报文段发往基准的连接(referenced connection)出现错误,TCP都会发出一个复位报文段。
    基准的连接:指由目的IP地址和目的端口号以及源IP地址和源端口号指明的连接。RFC 793也称之为插口。

    1. 到不存在的端口的连接请求
    产生复位的一种常见情况是当连接请求到达时,目的端口没有进程正在听(前提:目标主机系统启动状态)。
    对于UDP,当一个数据报到达目的端口时,该端口没在使用,它将产生一个ICMP端口不可达的信息。
    而对于TCP则使用复位。

    1. tcpdump -i eth0 tcp port 20000 and host 10.0.2.133
    2. telnet 10.0.2.133 20000

    image.png

    2. 异常终止一个连接
    有序释放(orderly release):
    终止一个连接的正常方式是一方发送FIN,因为在所有排队数据都已发送之后才发送FIN,正常情况下没有任何数据丢失

    异常释放(abortive release):
    发送一个复位报文段而不是FIN来中途释放一个连接。

    异常终止一个连接对应用程序来说有两个优点:
    (1)丢弃任何待发数据并立即发送复位报文段;
    (2)RST的接收方会区分另一端执行的是异常关闭还是正常关闭。应用程序使用的API必须提供产生异常关闭而不是正常关闭的手段。

    需要注意的是RST报文段不会导致另一端产生任何响应,另一端根本不进行确认。收到RST的一方将终止该连接,并通知应用层连接复位。
    1. 客户端非正常关闭,并发送复位连接(RST)
    2. 服务器端收到RST,不会返回ack,会产生 Connetct reset by peer 错误

    3. 检测半打开连接
    如果一方已经关闭或异常终止连接而另一方却还不知道,我们将这样的TCP连接称为半打开(Half-Open)的。
    任何一端的主机异常都可能导致发生这种情况。只要不打算在半打开连接上传输数据,仍处于连接状态的一方就不会检测另一方已经出现异常。
    半打开连接的另一个常见原因是当客户主机突然掉电而不是正常的结束客户应用程序后再关机