TCP协议的简介:
面向连接,可靠的基于字节流的传输层通信协议,将应用层的数据流分割成报文段发送给目标节点的TCP层,为了保证不丢包会为每个数据包打上序号,对方收到则发送ACK确认,未收则重传,使用校验和函数校验传输中是否有错误。
TCP报文头:
20位报文头 = 2位长度源端口 +2位长度的目标端口+4位长度的报文序列号+4位的ACK确认号(期望收到下一次报文的第一个字节的序号)+1位偏移位(由于头部有可选字段长度不固定,因此他指出TCP报文的报文体距离起始处有多远)+保留域+TCP控制位(8个)+Window窗口(用来告知发送端接受端的缓存的大小,以此达到发送端控制发送数据的速率和流量控制)+检验和(奇偶校验)+紧急指针(只有紧急标识位为1时有效)
常见的有六个标志位:
URG:紧急指针标记,为1为表示紧急指针有效,为0则说明无效
ACK:确认序号表示,为1时表示报文号有效,为0表示报文中不含确认信息,忽略确认号字段
PSH:PUSH标志,为1表示带有PUSH标志的数据,接受方接受到该数据时应尽快将数据发给应用程序而不是放在缓冲区排队
RST:重试连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接,或者用于拒绝非法的报文段和拒绝连接请求。
SYN:同步序号,用于建立连接过程,在连接过程中SYN等于1和ACK等于0表示数据段没有使用捎带的确认域,而连接应答稍带一个确认域的话即SYN等于1和ACK等于1
FIN:用于释放连接,为1时表示发送方已经没有数据可以发送了,即关闭本方数据流
三次握手的流程如下:
1、机器A创建传输控制块TCB向机器B发出连接请求,SYN=1,seq=x,此时客户后端就会静茹SYN-SENT的同步已发送的状态。
2、机器B如果同意连接会发送确认报文,确认报文中包含的两个位的字段SYN和ACK,此时机器B进入同步接受状态。
3、当机器A收到确认报文后还要向服务器给出一个确认报文,确认报文的ACK等于1,此时客户端进入ESTABLISHED状态,数据包可以携带也可以不携带,服务端收到客户端的确认后也会进入到ESTABLISHED的状态,之后机器A就可以和机器B之间就可以通信了。
常用的抓包工具:wireshark
为什么要三四握手才能建立连接:
主要是为了约定双方的Sequence Number,这个需要要作为以后数据通信的序号,以保证应用层接受到的数据不会因为网络问题而乱序。
第一次握手的隐患:SYN超时。针对恶意的SYN flood攻击,linux使用tcp_syncookies参数处理,即使服务端连接队列满了,服务器会根据源地址端口目标地址端口和时间戳打造出一个特别的Sequence Number回发给客户端,如果是攻击者是不会有响应的,如果是在正常连接则会发该cookie回发回来,然后服务端通过cookie建立连接。
四次挥手流程:
第一次挥手:客户端向服务端发送一个FIN包,用来关闭客户端到服务端的数据传送,此时客户端进入 FIN_WAIT_1状态。
第二次挥手:服务端收到客户端的断开连接请求后挥发一个ACK的确认包,服务器端进入到CLOSE_WAIT状态。
第三次挥手:服务端继续向客户端发送一个FIN包,服务器端进入到LAST_ACK的状态。
第四次握手:客户端接受到FIN后客户端进入到TIME_WAIT,并且给服务端一个确认包ACK,服务端收到后进入CLOSE状态,客户端等2MSL的时间后也关闭连接。
出现大量CLOSE_WAIT状态的原因:
1、检查代码,特别是释放资源的代码。
2、检查配置,特别是处理请求的线程配置。