文章目录
TCP连接
想象一下,当两台电脑需要传递数据的时候,应该在这两台电脑间建立一条通道,通过该通道来传输数据。这条通道就是我们所理解的TCP。而确定通道两端究竟是哪台电脑,则是通过套接字(Socket)。ip+端口,构成了套接字。ip则确定了主机。
所以两台电脑的通道则通过上述步骤简单的被建立起来了。
三次握手过程
根据TCP协议,在建立好上述的 “通道” 时,理应考虑好双方主机的能力。所以需要提前传递好一些参数(即连接的双方进行沟通),以此来约定好传输的内容要求。
所以经过考虑,三次握手的过程,足够双方确认好通道的要求。
- 第一步,由客户端向服务端发送SYN包。发送完后,客户端进入SYN_SENT状态。SYN包的意思:同步序列编号,是建立TCP/IP连接时候的握手信号,很小的一个数据包。可以想象为SYN(q=1)
- 第二步,服务端接收到SYN包后进入SYN_RCVD状态,通过返回一个ACK(q+1)来告诉客户端自己接收到了,并且返回一个自己的SYN(j)包
- 第三步,客户端接收到后,知道服务器的接收能力和发送能力正常,于是返回一个ACK(j+1)包,来告诉服务器自己的接收能力也正常。
每一步的作用
- 第一步,客户端确认自己的发送能力
- 第二步,服务端确认客户端的发送能力和自己的接收能力,客户端确认服务端的接收能力和自己的接收能力
- 第三步,服务端确认客户端的接收能力和自己的发送能力。
握手过程中可以确认的信息
- 对方报文发送的开始序号。
- 对方发送数据的缓冲区大小。
- 能被接收的最大报文段长度MSS。选择双方中较小的作为该值
- 被支持的TCP选项。
连接过程中的一些重要状态
半连接队列
服务器第一次接收到SYN包之后,会进入SYN_RCVD状态,此时连接还并没有完全建立,服务器会把该状态下的请求连接放进到一个队列当中,这个队列就称作半连接队列。
SYN-ACK包重传次数
在第二步过程中,服务器向客户端发送SYN-ACK包,如果没有收到客户端返回的确认包(ACK),则服务器会进行重传。重传的时间,以秒为单位,指数级别递增。超过一定的重传次数,则将连接信息从半连接队列中删除,并确认该次连接失败。
SYN攻击
服务器的资源分配是在二次握手的时候完成的,而客户端的资源分配是在三次握手的时候完成的。所以服务器容易遭到大量的SYN包的攻击。即客户端通过伪造大量不存在的ip地址来向服务器发送大量的SYN包,这些包的使得服务器需要通过大量的时间,来完成重传直至超时等待。导致正常的请求因为半连接队列满了而被丢弃。SYN 攻击是一种典型的 DoS/DDoS 攻击。
四次挥手过程
建立一个连接需要三次握手,而关闭一个连接却需要四次挥手,这是由于TCP连接的半关闭连接状态造成的。半关闭的意思就是,在连接断开的时候,连接的一端在没有发送能力之后,还拥有继续接受消息的能力。
- 第一步。某一端(可以是服务端也可以是客户端)发送一个FIN包,并且自身进入FIN_WAIT1状态。进入该状态后,主动关闭TCP连接,等待被动端的确认。FIN包中包含了一个序列号(q=1)。
- 第二步。服务端接收到该包后,发送一个ACK包给客户端,该ACK包的值就是之前FIN包中的序列号值+1。然后服务端就进入到了CLOSE_WAIT状态。此时TCP处于半关闭状态,主动发起断开连接的那一端到被动的那一端的连接释放。主动端进入FIN_WATI2状态,等待被动端发送的连接释放报文。
- 第三步。如果被动端也要断开连接了,则也会发一个FIN包,且同样指定了一个序列号(w=1),并进入LAST_ACK状态。即被动端发送了连接释放报文。
- 第四步。主动端接收到连接释放报文后,同样返回一个确认码ACK(w+1)给被动端,并且等待一会(由等待计时器设置的时间),确保被动端接收到之后,才会由FIN_WAIT2状态进入CLOSED状态。
四次挥手释放连接时,等待2MSL的意义?
因为四次挥手最后,被动端要等待主动端发送的ACK包,
- 如果不等待的话,可能导致最后一个ACK包的丢失,那么被动端就不能进入连接关闭状态了。
- 经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。
挥手四次的意义
关闭连接时,当服务端收到FIN报文时,并不会立即关闭SOCKET,所以先回复一个ACK报文。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。需要四次才行。