TCP的三次握手

说说TCP的三次握手

TCP三次握手的流程
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认。
第二次握手:服务器收到SYN包,必须确认客户SYN(同时ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
TCP的三次握手
为什么需要三次握手才能建立连接
为了初始化Sequence Number的初始值SYN

首次握手的隐患—SYN超时
问题起因分析
(1)Server收到Client的SYN,回复SYN-ACK的时候未收到ACK确认
(2)Server不断重试直至超时,Linux默认等待63秒才断开连接
针对SYN Flood的防护措施
(1) SYN队列满后,通过tcp_syncookies参数回发SYN Cookie
(2)若为正常连接则Client会回发SYN Cookie,直接建立连接

建立连接后,Client出现故障怎么办
保活机制
(1)向对方发送保活探测报文,如果未收到相应则继续发送
(2)尝试次数达到保活探测数仍未收到响应则中断连接

1. 传输控制协议TCP简介
面向连接的、可靠的、基于字节流的传输层通信协议
将应用层的数据流分割成报文段并发送给目标节点的TCP层
数据包都有序号,对方接收到则发送ACK确认,未收到则重传
使用校验和来检验数据在传输过程中是否有误
2. TCP Flags
URG:紧急指针标志。为1时表示紧急指针有效,为0时表示忽略紧急指针。
***ACK:确认序号标志。***为1时表示确认号有效,为0时表示报文中不含确认信息,忽略确认号字段。
PSH:push标志。为1时表示带有push标志的数据,指示接收方在接收到该报文段以后应尽快将报文段交给应用程序,而不是在缓冲区排队。
RST:重置连接标志。用于重置由于主机崩溃或其他原因而出现错误的连接,或者用于拒绝非法的报文段拒绝连接请求。
***SYN:同步序号,用于建立连接过程。***在连接请求中SYN等于1和ACK等于0表示该数据段没有使用捎带的确认域。而连接应答捎带一个确认即SYN等于1和ACK等于1。
**FIN:finish标志,用于释放连接。**为1时表示发送方已经没有数据发送了,即关闭本方数据流。
3.握手是为了建立连接,TCP三次握手的流程图如下:
TCP的三次握手
假设A和B首次进行通信,一开始的时候客户端和服务器端都会处于CLOSED的状态,假设主动打开连接的是客户端,被动打开连接的是服务端,刚开始的时候TCP服务器进程先创建传输控制块TCB时刻准备接收其他客户进程发送过来的连接请求,此时服务端进入LISTEN即监听的状态,此时TCP客户端进程也是先创建一个传输控制块TCB,向服务器发出连接控制请求报文,SYN=1,seq=x,这就是我们报文头里的TCP flag中的同步序号 x可以是一个任意的正整数值,TCP客户端进程就进入了SYNSENT同步已发送状态,此时发送过去的 SYN=1,seq=x 这个数据包报文段,这个报文段是不能携带数据的,但是要消耗掉一个序号,**这便是第一次握手。**那当我们的服务器接收到我们的请求报文之后,如果同意连接,则发出确认报文,确认报文中包含了TCP flag 中的两个为1的字段 ACK=1 , SYN=1 确认号:ack=x+1,同时也要为自己的缓存初始一个***即 seq=y,此时服务器就进入了SYNRCVD即同步收到的状态,这个报文也是不能携带数据的,并且同样需要消耗一个序号,**这便是第二次握手。**那么当TCP客户进程收到确认报文之后还要向服务器给出一个确认,确认报文的ACK=1,ack=y+1(原因是刚刚服务器给发了一个seq=y,所以作为回应ack=y+1,同时由于我先前,我的序号已经被ack=x+1了,所以自己的序号seq=x+1),此时TCP连接建立,客户端进入了ESTABLISHED建立连接的状态,TCP规定这个报文段可以携带数据,(前两个报文段都是不可以携带数据的,第三个可以携带也可以不携带,如果不携带数据就不会消耗序号)**这便是第三次握手。**那当服务器收到客户端的确认后,也会进入ESTABLISHED的状态,此后双方就可以进行通信了。