架构性能优化_TCP详解_三次握手(建立连接)

一、 TCP报文格式

架构性能优化_TCP详解_三次握手(建立连接)_第1张图片

架构性能优化_TCP详解_三次握手(建立连接)_第2张图片

上图中有几个字段需要重点介绍下:
  

(1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  

(2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
  

(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
  

(A)URG:紧急指针(urgent pointer)有效。
  

(B)ACK:确认序号有效。
  

(C)PSH:接收方应该尽快将这个报文交给应用层。
  

(D)RST:重置连接。
  

(E)SYN:发起一个新连接。
  

(F)FIN:释放一个连接。

需要注意的是:
  

(A)不要将确认序号ack与标志位中的ACK搞混了。
  

(B)确认方Ack=发起方Req+1,两端配对。



二、三次握手(建立tcp连接)
所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,握手过程如下图:

架构性能优化_TCP详解_三次握手(建立连接)_第3张图片
正常建立连接过程描述:
1、第一次握手:客户端向服务器端发送一个数据包,里面包括标志位SYN置为1,seq序号随机生成一个值为J,此时,客户端状态为SYN_SENT,等待服务器端的请求确认。
2、第二次握手:服务器端收到客户端发送的数据包,拆包后得到相关信息,由标志位SYN=1得知客户端要请求建立连接,于是再向客户端发送一个新的数据包,里面包括确认号ack=J+1,标志位ACK置为1,seq序号随机产生一个值K,标志位SYN置为1,此时,服务器端状态为SYN_RCVD,表示第一次握手成功了,再发给服务器端一个确认数据包就可以建立连接了。
3、第三次握手:客户端收到服务器端发送的数据包,拆包后得到相关信息,由标志位SYN=1和ACK=1得知服务器端已经收到请求确认了,客户端检查确认号ack是否J+1,标志位SYN是否为1,标志位ACK是否为1,检验后,此时,客户端的状态为ESTABLISHED,表示已经建立连接,客户端再向服务器端发送一个新的数据包,里面包括确认号ack=K+1,标志位ACK置为1;服务器端收到数据包后,检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,此时,服务器端的状态为ESTABLISHED。


常见异常情况(非正常建立连接情况,也是linux内核优化所关注的点):
1、TCP第三次握手失败怎么办?
当客户端收到服务端的SYN+ACK应答后,其状态变为ESTABLISHED,并会发送ACK包给服务端,准备发送数据了。如果此时ACK在网络中丢失,过了超时计时器后,那么Server端会重新发送SYN+ACK包,重传次数根据/proc/sys/net/ipv4/tcp_synack_retries来指定,默认是5次。如果重传指定次数到了后,仍然未收到ACK应答,那么一段时间后,Server自动关闭这个连接。但是Client认为这个连接已经建立,如果Client端向Server写数据,Server端将以RST包响应,方能感知到Server的错误。

总结:因此可以调整linux内核参数/etc/sysctl.conf的net.ipv4.tcp_synack_retries = 1来减少丢包后重传的时间,以优化系统的高并发性能


2、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

总结:因此可以调整linux内核参数/etc/sysctl.conf的net.ipv4.tcp_syncookies = 1,该值表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;


3、如果已经建立TCP连接,但是客户端已经掉线,服务器端怎么办?
已经建立连接后,如果客户端久久发送数据,未响应,则服务器端会重新发送数据检测客户端是否已经掉线,如果超过重新发送检测次数,则断开连接,释放资源。
总结:因此可以调整linux内核参数/etc/sysctl.conf的net.ipv4.tcp_retries2 = 5,控制内核向已经建立连接的远程主机重新发送数据的次数,低值可以更早的检测到与远程主机失效的连接,因此服务器可以更快的释放该连接,可以修改为5





你可能感兴趣的:(linux)