TCP是一种面向连接的可靠传输协议,序列号和确认号是保证TCP可靠传输的一种重要机制。
在TCP协议中,每个数据包都有一个序列号seq和一个确认号ack。
序列号表示这个数据包中的第一个字节在整个数据流中的位置。
对于发送方来说,序列号用来跟踪已发送的字节数。
而接收方则通过序列号来确定自己是否接收到正确的数据。
确认号表示接收方期望下一个收到的字节的位置。
接收方在收到数据后,发送确认号给发送方,告知已成功接收到的数据。
发送方在接收到确认号后,会根据确认号来确定哪些数据已经被成功接收,哪些数据需要进行重传。
在TCP三次握手时:
首先,客户端向服务器发送SYN,产生一个随机数x作为客户端的初始seq,所以此时seq=x,ack=0。
接着,服务器回复SYN和ACK,产生一个随机数y作为服务器的初始seq,ack等于上一个收到报文的seq+1,也就是客户端SYN报文的seq+1(SYN报文,TCP当做传输1个字节),即x+1。所以此时seq=y,ack=x+1。
最后,客户端回复服务器ACK,seq等于上一个自己发送报文的seq+1, 也就是SYN报文的seq+1,即x+1。而ack等于上一个收到报文的seq+1,即服务器SYN和ACK报文的seq+1(SYN报文,TCP当做传输1个字节),即y+1。所以此时seq=x+1,ack=y+1。
同一个tcp连接中,在第一次握手客户端生成随机数x作为初始seq,第二次握手服务器生成随机数y作为初始seq后,后续报文的seq和ack的变化都是有规律的,每个TCP报文的seq都等于上一次自己发送报文的seq加上tcp负载数据长度,如果上一次发送的报文是SYN报文或者FIN报文,则认为TCP负载数据长度为1。
而每个TCP报文的ack都等于上一次自己收到报文的seq加上tcp负载数据长度。
如果上一次收到的是SYN报文或者FIN报文,则认为TCP负载数据长度为1。