实线 :表示客户的正常状态转换 虚线 :表示服务器的正常状态装换
应用 :表示状态转换在应用进程发起操作时发生
接受 :表示状态转换在接受到分节时发生 发送 :表示这个转换发送什么
三次握手建立连接
服务器调用 socket 、 bind 、 listen 来完成,即执行被动打开,准备好接受外来的请求。
1. 客户端发调用 connect 发送 SYN 分节(同步),它告诉服务器客户将在连接中发送的数据的初始序列号。此时客户端进入 SYN_SENT 状态。
2. 服务器接受到客户端 SYN 分节后,必须进行确认,同时发送一个 SYN 分节到客户端。服务器发送 ACK+SYN 后,服务器进入 SYN_RECV 状态。
3. 客户端收到服务器发送的 SYN, 并进行确认。客户端发送 ACK 后进入 ESTABLISHED 状态,服务器接收到 ACK 后也进入到 ESTABLISHED 状态。
l 当客户端与服务器都进入 ESTABLISHED 状态后,就说明 TCP 连接成功建立。
l 当客户端处于 SYN_SENT 状态,如果没有收到 ACK (超时),客户端会多次(几次?)重发 SYN ,如果连接仍未能建立,则进入 CLOSED 状态。
l 当服务器处于 SYN_RECV 状态时,如果收到 RST 分节,则进入 CLOSED 状态。 SYN_RECV 状态的服务器没有收到 ACK 时,其一直处于半连接状态,其信息会存在服务器的缓冲区中,直到超时, SYN Flood 攻击就是靠大量的半连接 SYN 来耗尽服务器的资源。
l 同时打开:为了处理同时打开,对于同时打开它仅建立一条连接而不是两条连接。两端几乎在同时发送 SYN ,并进入 SYN_SENT 状态。当每一端收到 SYN 时,状态变为 SYN_RCVD ,同时他们都再发 SYN 并对收到的 SYN 进行确认。当双方都收到 SYN 及相应的 ACK 时,状态都变为 ESTABLISHED 。
四次挥手断开连接
1. 某个应用进程首先调用 close ,执行主动关闭,导致发送一个 FIN 分节,表示数据发送完毕,进入 FIN_WAIT_1 状态。
2. 接受 FIN 的另一端执行被动关闭,其确认收的 FIN ,接受到的 FIN 作为文件结束符传递给接收端的应用进程(放在已排队等候该应用进程接受的任何其它数据之后),进入 CLOSE_WAIT 状态。同时原发送端接受到 FIN 后进入 TIME_WAIT_2 状态。
3. 一段时间后,接收到文件结束符的应用进程将调用 CLOSE 关闭它的套接口,向对端发送一个 FIN ,进入 LAST_ACK 状态。
4. 接受到这个 FIN 的原发送端对它进行确认,发送 ACK ,并进入 TIME_WAIT 状态,在此状态保留 2MSL 时间后,进入 CLOSED 状态。而另一端收到 ACK 后进入 CLOSED 状态。
l 被动关闭的一段的 ACK 与 FIN 可能同时发送(捎带),则主动关闭的一端由 TIME_WAIT_1 直接进入 TIME_WAIT 状态。
l 主动关闭一端存在 TIME_WAIT 状态的原因。
1. 如果主动关闭端最后发送的 ACK 丢失,则被动关闭一端将重发 FIN ,此时主动关闭一端必须重发最后的 ACK ,所以其不能再发送 ACK 后立即进入 CLOSED 状态。
2. 防止 IP 和端口立即被重用,而还在“线上”的数据将影响重用的进程。 2MSL 的时间允许某个方向的分组最多存活 MSL 时间即被丢弃。
l 同时关闭:当应用层发出关闭命令,两端均从 ESTABLISHED 变为 FIN_WAIT_1 。这将导致双方各发送一个 FIN ,两个 FIN 经过网络传送后分别到达另一端。收到 FIN 后,状态由 FIN_WAIT_1 变为 CLOSING ,并发送最后的 ACK 。当收到最后的 ACK ,状态变为 TIME_WAIT 。