TCP序列号和确认号详解

简介与作用

     TCP协议工作在OSI的传输层,是一种可靠的面向连接的数据流协议,TCP之所以可靠,是因为它保证了传送数据包的顺序。顺序是用一个序列号来保证的。响应包内也包括一个序列号,表示接收方准备好这个序列号的包。在TCP传送一个数据包时,它会把这个数据包放入重发队列中,同时启动计时器,如果收到了关于这个包的确认信息,便将此数据包从队列中删除,如果在计时器超时的时候仍然没有收到确认信息,则需要重新发送该数据包。另外,TCP通过数据分段中的序列号来保证所有传输的数据可以按照正常的顺序进行重组,从而保障数据传输的完整。 .

 

在TCP通讯中主要有连接的建立、数据的传输、连接的关闭三个过程!每个过程完成不同的工作,而且序列号和确认号在每个过程中的变化都是不同的。 
 
TCP建立连接

TCP建立连接也就是我们常说的三次握手,我们这里以客户端向服务器端发起连接为例来说明序列号和确认号。

 

客户端向服务器发送一个同步数据包请求建立连接,该数据包中,初始序列号(ISN)是客户端随机产生的一个值2712239078, 确认号是0

 
服务器收到这个同步请求数据包后,会对客户端进行一个同步确认ACK。这个数据包中,序列号是服务器随机产生的一个值1288781508 ,确认号是客户端的初始序列号+1 (2712239078+1=2712239079) 
 
客户端收到这个同步确认数据包后,再对服务器进行一个确认。该数据包中,序列号是上一个同步请求数据包中的确认号值2712239079 ,确认号是服务器的初始序列号+1 (1288781508+1=1288781509)
 
 
TCP传输数据

    这里客户端主动向服务器发送一个GET请求,来提交自己的请求信息。
 
该数据包中,序列号为2712239079,确认号为1288781509,这和三次握手的第三步的数据包中的序列号和确认号相同。
从图4中看出这个数据包的大小为1018字节,其中减去14字节Ethernet报头,20字节的IP报头,20字节的TCP报头和4字节的FCS(1018-14-20-20-4=960),得到传输的数据大小为1432。我们将该数据包中的序列号加上该数据大小(即2712239079+960=2712240039),发现与“下一个序列号”的值完全吻合,也就是下一个数据包中服务器发送给客户端的数据包中的确认号 
 
 
确认收到 
 
三次握手(总结)

   Client --> 置SYN标志 序列号 = J,确认号 = 0 ----> Server

    Client <-- 置SYN标志 置ACK标志 序列号 = K, 确认号 = J + 1 <-- Server

    Clinet --> 置ACK标志 序列号 = J + 1,确认号 = K + 1 --> Server
 
链接建立后,接下来Client端发送的数据包将从J + 1开始,Server端发送的数据包将从K + 1开始,这里要说明的是:建立链接时,Client端宣称自己的初始序列号是J,Server端宣称自己的初始序列号是K,但是建立连接后的数据包却各自中初始序列号+1开始,这是因为SYN请求本身需要占用一个序列号 
 
数据传输(总结)

    Client --> 置PSH标志,置ACK标志 序列号 = 55555, 确认号 = 22222,数据包长度 = 11 ---> Server

     Client <-- 置ACK标志,序列号 = 22222, 确认号 = 55566 (=55555 + 11),数据包长度 = 0 <--- Server

    Client <-- 置PSH标志,置ACK标志 序列号 = 22223, 确认号 = 55566,数据包长度 = 22 <--- Server

    Client --> 置ACK标志,序列号 = 55566, 确认号 = 22244(=22222+22),数据包长度 = 0 ---> Server
 
TCP的建立与终止
 
三次握手状态迁移图

客户端   CLOSED->SYN_SENT->ESTABLISHED->

服务器   CLOSED->LISTEN->SYN收到->ESTABLISHED 

CLOSED: 表示初始状态。
LISTEN: 表示服务器端的某个SOCKET处于监听状态,可以接受连接了
SYN_RCVD: 这个状态表示接受到了SYN报文,并发出ACK 包
SYN_SENT: 当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报      文。SYN_SENT状态表示客户端已发送SYN报文。
ESTABLISHED:表示连接已经建立
 
 
四次挥手
客户端  FIN_WAIT_1>FIN_WAIT_2->TIME_WAIT->CLOSED
服务器  CLOSE_WAIT->LAST_ACK->CLOSED
 
 
FIN_WAIT_1: 当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报      文后,则进入到FIN_WAIT_2状态,
 
FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点       数据需要传送给你,稍后再关闭连接。
 
TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文就等2MSL(2倍最大生存时间)后即可回到CLOSED可用状态了。
 
CLOSE_WAIT: 这种状态的含义其实是表示在等待关闭。当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入
到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。
 
nLAST_ACK: 它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。

 

posted @ 2011-12-19 14:14  陈英俊  阅读(8010)  评论(0编辑  收藏  举报