一、首先来明确几个概念
SYN 标志位 1表示连接请求标识 其他为0
ACK 标志位 最初建立连接时为0,其他为1
FIN 标志位 1表示结束连接请求 默认为0
PSH 标志位 置为1,tcp不再等待缓存满了以后再交付应用层处理,而是立即交于应用层
RST 标志位 各种异常情况强制关闭连接
seq 随机生成的序列号,一般工具展示相对序列号(从0开始),如果用相对序列号,seq表示总共发送多少字节数据
ack seq+已经接收的字节数,如果seq用相对序列号,ack表示总共接收到多少字节数据,字节数不包括tcp首部、ip首部和帧校验
二、再来说说tcp建立连接三次握手
A端发送SYN为1的连接请求,此时seq=x,状态为SYN_SENT,B端接到请求,发送SYN和ACK都为1的连接请求,此时seq=y,ack=x+1,状态由LISTEN变为SYN_RCVD A端接收到B端的连接请求,再次发送ACK=1的确认,此时seq=x+1,ack=y+1,状态变为ESTABLISHED,B端接收到A端的确认请求,状态变为ESTABLISHED,连接建立完成。
为什么不能两次握手,而要三次,如果A到B最后一次确认不发送,那B端收到A端第一次请求,就要完成连接的建立,当A端迟迟没有收到B端的建立连接请求,A端会重新发起连接请求,当B端再次收到连接请求,会重新申请资源建立连接,此时A端收到B端的第一次确认和连接请求,A端不会建立两个连接,而是会把第一次接收到的消息扔掉,这样就会造成,A端只有一个连接资源,B端有两个连接资源,造成B端资源的浪费。
疑问:
在说疑问前,先说说tcp是如何区分两次连接的,如果AB端ip地址固定,也只能根据A端的端口号来区分不同的tcp连接,如果是不同主机建立的连接,ip地址自然是不一样的
那好,再来说说疑问,如果A端迟迟没有收到B端的确认和连接请求,A端为什么不再次发起一个相同端口号的连接请求,这样B端就不用再次申请连接资源,而是直接用第一次建立好的连接,我猜想是tcp这样控制,应该会增加不小的复杂度,所以tcp每次发起的连接都是新连接,不管是首次发送还是超时后再次发送。