TCP相关问题极简分析
TCP
TCP:全双工可靠传输,面向字节流传输
Tcp三次握手
① Server处于空闲监听LISTEN状态
② Client发送SYN连接请求,然后处于SYS_SENT状态 (第一次握手)
③ Server收到请求,发送ACK应答,表示收到了请求,同时间再发送SYN信号给Client,表示可以建立连接了。此时Server处于SYN_RECD状态 (第二次握手)
④ Client收到Server的回复后,发送ACK应答,表示收到了回复,此时连接建立。Client处于ESTABLISH状态 (第三次握手)
⑤ Server收到ACK后,也处于ESTABLISH状态
⑥ 开始数据传输
不能两次握手的原因:
假如两次握手。
① Client第一次发送连接请求,此时网络阻塞,Client收不到Server发回的应答信号,就会认为自己发送的连接请求丢失,重新发送请求。(超时重传)
② Client第二次发送请求,此时网络畅通,Server收到请求并应答。Client收到应答,两者建立连接。
③ Server和Client正常进行数据传输,结束业务后释放连接。Client关闭连接处于CLOSE状态,Server重新监听。
④ 此时Client第一次发送的连接请求到达了Server,Server认为有新的连接请求进来了,就发送应答信号。
⑤ 但是Client此时是处于CLOSE状态,无法传输数据。
⑥ Server就会一直等待Client传输数据,白白浪费了Server资源。
如果是三次握手:Server没有收到Client发送的ACK应答,就会自动关闭连接,释放资源。
还有一个原因:
如果是两次握手,Client发送连接请求(第一次握手),Server回应请求(第二次握手),此时Client就知道了Server有接收和发送信息的能力。但是,Server只知道Client有发送信息的能力,却不知道Client有没有接收的能力。这就违背了TCP是可靠连接的性质。
SYN洪泛攻击
攻击者在伪造客户端IP地址发送syn请求(第一次握手),服务端收到后发送应答(第二次握手),但是这个应答永远到达不了真正的客户端地址,服务端就无法收到客户端的应答,导致服务端资源浪费。
Tcp四次挥手
连接终止协议
① Client和Server处于连接建立状态ESTABLISHED
② Client发出连接断开请求FIN,此时Client处于FIN_WAIT_1状态 (第一次挥手)
③ Server收到断开请求,发出应答信号ACK,告诉Client收到了断开请求,此时Server处于半关闭CLOSE_WAIT状态**(第二次挥手)**
④ Client收到应答,处于FIN_WAIT_2,等待Server发送关闭信号。(因为TCP是全双工的,所以需要双方都确认关闭,才能断开TCP连接)
⑤ Server处理完所有数据后,发送FIN请求,告诉Client数据传输完成,现在可以断开连接了。此时Server处于LAST_ACK状态,接收最后的断开应答。(第三次挥手)
⑥ Client收到Server的FIN请求后,发送ACK信号,此时Client处于TIME_WAIT状态 (第四次挥手)
⑦ Server收到ACK信号后,直接处于CLOSED状态。
⑧ Client还需要等待2*MSL(报文往返时间)才会处于CLOSED状态
为什么Client还需要等待2*MSL(报文往返时间)才会处于CLOSED状态?
-
确保最后一个确认报文能够到达。如果没能到达,服务端就会会重发FIN请求释放连接。等待一段时间没有收到重发就说明服务端已经CLOSE了。如果有重发,则客户端再发送一次ACK信号。主要就是确保TCP的可靠连接。
-
让还存留在网络中的报文消失,避免重复报文对下次连接请求产生混淆。
为什么不能三次挥手?
很简单,因为要保证双方的数据都发送完成,确实任意一次挥手都无法保证。