如何理解状态图, 缺少一个 rst 状态,类似于 closed. 几个观点
1. syn,ack或者 fin,ack 可以同时发送, 但是接受需要分别接收来设计状态.
2. Fin 这种是需要业务端触发的, ack ,rst ,syn 这种是 tcp 协议本身自动触发的.
3. 建连的时候分服务端,客服端. 由于 tcp 是双工的, 后续数据传输和关闭连接不分服务端,客服端.
4. 其他深入观点, 4.1 经过lvs dr负载均衡的连接是三角形. [对栈连接池不友好] 4.2 lvs 的负载均衡是在连接时完成的.
5. lvs 其实也是监听了端口,但是其接受到了 syn 后,不返回 ack,而是转发了 syn 数据. 相当于没有使用 tcp 协议,拦截处理了.
案例1: 连接池中的 tcp 超时案例. 更复杂是防火墙断开长连接. 牛在看堆栈发现问题. [3]
案例2: 被动 close 后, 照样可以 read,但是返回-1. 代表不可能有新的流了. 原因自身的状态已经是 close_wait. 自己主动 close 的,再 read 会抛已关闭. [4]
案例3: 如果状态不符合,更新数据.会导致 connection 被 reset . 上一次 rst 后下一次应该判断在状态, 连接正常才能往里面发送数据. 然后再次写时,直接抛错broken pipe . 这种情况一般发生在客户进程不理会(或未及时处理)Socket 错误,继续向服务 TCP写入更多数据时.有可能 flush 成功,但是对方未收到数据的情况. 所以发送成功,要看 ack 信息(应用层是 返回 success 信息),不能单方便认为发送成功. [4]
[1] FIN_WAIT_2 tcp状态多原因剖析和解决 服务器关闭
[2] 常见socket读写异常及错误
[3] 一则线上MySql连接异常的排查过程 部分引文"然后问了应用与数据库是不是在不同网段上,马上建议找网络的人查一下防火墙对tcp长连接超时的设置。" https://www.2cto.com/database/201505/402016.html