TCP(Transmission Control Protocol)传输控制协议是一种面向连贯的、牢靠的、基于字节流的传输层协定。从TCP的定义中能够看出,TCP是面向连贯的牢靠的通信形式,连贯单方都须要确定各自的连贯通道都是OK的。三次握手的目标就是为了确定各自的通道是OK的,同时告诉对方本人的起始SEQ。当客户端调用connect函数时便发送了SYN报文同时告诉对方本人的起始SEQ,从而发动第一次握手,客户端进入SYN_SENT状态;服务端收到SYN报文后,返回SYN+ACK报文到客户端同时告诉对方本人的起始SEQ,从而发动了第二次握手,服务端进入SYN_RCV状态;客户端收到服务端的SYN+ACK后,回复ACK报文,从而发动第三次握手,客户端进入ESTABLISHED状态;服务端收到ACK报文后服务端进入ESTABLISHED状态。自此三次握手就实现了,其流程图如下:
TCP的三次握手
过程如下:
客户端调优
1、当客户端发动第一次握手的时候,如果迟迟收不到对方的应答,那么客户端会重试,重试的次数由/proc/sys/net/ipv4/tcp_syn_retries管制,默认值是5,重试距离是1,2,4,8,16,32,总共须要破费63s。能够依据客户端与服务端的网络情况以及服务端的负载,适当升高重试次数调小,如2次,从而出现异常的时候,客户端能够尽快感知到异样。
服务端调优
1、当服务端发动第二次握手的时候,如果迟迟收不到对方的应答,那么服务端也会重试,重试的次数由/proc/sys/net/ipv4/tcp_synack_retries管制,默认值是5,重试距离是1,2,4,8,16,32,总共须要破费63s。同样的,如果客户端与服务器的网络情况挺好的,能够把重试次数调小。
2、当服务端发动第二次握手后,会把连贯放入到半连贯队列,队列的大小由/proc/sys/net/ipv4/tcp_max_syn_backlog管制,默认大小是2048。当这个队列满时,服务器将无奈建设连贯。那么咱们怎么晓得这个队列是否有溢出呢?能够通过如下的命令看到
netstat -s | grep 'SYNs to LISTEN'75571 SYNs to LISTEN sockets ignored
这个是个累计值,如果发现这个值一直的变大,能够把这个队列调大。同时还能够设置/proc/sys/net/ipv4/tcp_syncookies=1,关上tcp_syncookies性能。tcp_syncookies能够取如下的值:
A. tcp_syncookies=0时,敞开syncookies性能,当半连贯队列满时,服务端将无奈建设连贯;
B. tcp_syncookies=1时,当半连贯队列满时,服务端将启用syncookies性能;
C. tcp_syncookies=2时,服务端将始终启用syncookies性能。
tcp_syncookies的次要工作流程如下:
服务端接管到SYN报文并返回TSYN+ACK报文时,不插入半连贯队列,而是依据这个SYN报文计算出一个cookie值。这个cookie作为将要返回的SYN ACK报文的初始序列号。当客户端返回一个ACK报文时,依据报文头信息计算cookie,与返回的确认序列号(初始序列号+1)进行比照,如果雷同,则是一个失常连贯,而后将连贯放入accept队列。
如果通过netstat -lap发现SYN_RCV状态的连接不断的增长,那么就须要通过抓包工具剖析是不是产生了syn泛洪攻打,如果产生了泛洪攻打,须要通过防火墙阻止这种连贯。
所谓的SYN泛洪攻打利用的是TCP的三次握手机制,攻打端利用伪造的IP地址向被攻打端发出请求,而被攻打端收回的响应报文将永远发送不到目的地,那么被攻打端在期待敞开这个连贯的过程中耗费了资源,如果有大量的这种连贯,主机资源将被耗尽,从而达到攻打的目标。
3、当服务端收到第三次握手的ACK应答报文后,服务端会把连贯放入accept队列,accept队列由listen()函数传入的参数(参数的值能够通过ss -lnt命令的输入“Send-Q”列查看)与/proc/sys/net/core/somaxconn独特管制,取2者的小值。能够通过如下的命令查看是否由溢出:
netstat -s | grep overflow75571 times the listen queue of a socket overflowed
如果这个值一直的变大,阐明应用程序没有及时的调用accept函数接管连贯,能够先调高上文进步的2个参数。
accept队列满后是否抛弃连贯,是由参数/proc/sys/net/ipv4/tcp_abort_on_overflow管制,默认是0。如果设置为1并且溢出,则发送RST报文敞开连贯。个别倡议设置为0,因为抛弃后,客户端如果发送了数据+ACK,因为等不到应答,那么就会反复发送数据+ACK,当服务端接管到ACK后,如果accept队列不满了,那么连贯就建设了。可见tcp_abort_on_overflow=0,能够进步TCP连贯建设胜利的概率。只有accept队列长期溢出的时候,才设置tcp_abort_on_overflow=1。
4、另外还能够关上TFO性能,进步TCP连贯建设的效率,TFO详见文档:
https://tools.ietf.org/html/r...
https://www.cnblogs.com/passz...