TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接,四次挥手断开连接。
三次握手
是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接建立成功。在socket编程中,这一过程由客户端执行connect来触发。完成三次握手,随后Client与Server之间可以开始传输数据了
SYN攻击:
在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:
#netstat -nap | grep SYN_RECV
Q : 为什么要三次握手, 两次不可以吗?
A : 试想一下, A第一次发送请求连接, 但是在网络某节点滞留了, A超时重传, 然后这一次一切正常, A跟B就愉快地进行数据传输了. 等到连接释放了以后, 那个迷失了的连接请求突然到了B那, 如果是两次握手的话, B发送确认, 它们就算是建立起了连接了. 事实上A并不会理会这个确认, 因为我压根没有要传数据啊. 但是B却傻傻地以为有数据要来, 苦苦等待. 结果就是造成资源的浪费.
更加接地气的解释就是 : A打电话给B
第一次握手 : 你好, 我是A, 你能听到我说话吗第二次握手 : 听到了, 我是B, 你能听到我说话吗第三次握手 : 听到了, 我们可以开始聊天了三次握手其实就是为了检测双方的发送和接收能力是否正常, 你说呢?
四次挥手
指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发, 由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN(finish)来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。实际中还会有出现同时发起主动关闭的情况
Q : 为什么要四次挥手, 而不是两次, 三次?
A :
首先, 由于TCP的全双工通信, 双方都能作为数据发送方. A想要关闭连接, 必须要等数据都发送完毕, 才发送FIN给B. (此时A处于半关闭状态)
然后, B发送确认ACK, 并且B此时如果要发送数据, 就发送(例如做一些释放前的处理)
再者, B发送完数据之后, 发送FIN给A. (此时B处于半关闭状态)
然后, A发送ACK, 进入TIME-WAIT状态
最后, 经过2MSL时间后没有收到B传来的报文, 则确定B收到了ACK了. (此时A, B才算是处于完全关闭状态)
PS : 仔细分析以上步骤就知道为什么不能少于四次挥手了.
Q : 为什么要等待2MSL(Maximum Segment Lifetime)时间, 才从TIME_WAIT到CLOSED?
A : 在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
更加接地气的解释 :
第一次挥手 : A告诉B, 我没数据发了, 准备关闭连接了, 你要发送数据吗第二次挥手 : B发送最后的数据第三次挥手 : B告诉A, 我也要关闭连接了第四次挥手 : A告诉B你可以关闭了, 我这边也关闭了