目录
一、TCP报文头结构定义
其中:
seq是32位序号,ack是32位确认序号
-》
URG:紧急指针标志
ACK:确认序号标志
PSH:push标志
RST:重置连接标志
SYN:同步序号,用于建立连接过程
FIN:finsh标志,用于释放连接
二、TCP三次握手
初始时,服务器端处于LISTEN监听状态
第一次握手:客户端发送SYN包到服务器(SYN标志位为1,seq=x)并进入SYN-SENT状态,等待服务器确认;
第二次握手:服务端确认客户端的SYN包(ACK标志位为1,ack=x+1),同时自己也发送一个SYN包(SYN标志位为1,seq=y),并且进入到SYN-RCVD状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送一个确认包(ACK标志位为1,ack=y+1),此包发送完毕,客户端和服务器端进入ESTABLISHED状态,完成三次握手。
可能出现的问题及解决方案:
1.Server收到Client的SYN,回复SYN+ACK的时候未收到ACK确认。则Server不断重试直至超时,Linux默认等待63秒才断开连接。
SYN超时可能会带来恶意代码攻击,应对SYN Flood的防护措施是:
->SYN队列满后,通过tcp_syncookies参数回发SYN Cookie,若为正常连接则Client会回发SYN Cookie,直接建立连接。
2.建立连接后,Client出现故障怎么办?
保活机制:
向对方发送保活探测报文,如果未收到响应则继续发送,尝试次数达到保活探测次数仍未收到响应则中断连接
三、TCP的四次挥手
第一次挥手:客户端发送一个FIN包(FIN=1,seq=u),用来关闭客户端到服务端的数据传送,之后客户端进入FIN_WAIT-1状态;
第二次挥手:服务端接收到FIN后,发送一个ACK给客户端,确认序号ack为收到序号seq+1(与SYN相同,一个FIN占用一个序号),服务端进入到CLOSED_WAIT状态,客户端进入到FIN-WAIT-2状态;
第三次挥手:服务端发送一个FIN,用来关闭服务端到客户端的数据传送,并且服务端进入LAST_ACK状态;
第四次挥手:客户端收到FIN后,客户端进入TIME_WAIT状态,接着发送一个ACK给服务端,确认序号ack为收到序号seq+1.紧接着服务器端进入CLOSED状态,完成四次挥手
为什么会有TIME_WAIT状态?
1.确保有足够的时间让对方收到ACK包
2.避免新旧混淆
( 假设最终的ACK丢失,服务端将重发FIN,客户端必须维护TCP状态信息以便可以重发最终的ACK,否则会发送RST,结果主机认为发生错误。TCP实现必须可靠地终止连接的两个方向(全双工关闭),客户端必须进入 TIME_WAIT 状态,因为客户端可能面临重发最终ACK的情形。)
注:TIME_WAIT:
表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN WAIT1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。(主动方)