首先服务端Bd的服务进程处理监听的状态,等待客户端来连接 (1)当客户端A要和B通信建立TCP连接时,首先会发送一个连接请求报文给服务端B. 在这个请求报文中,TCP首部中SYN位设置为1,ACK位设置为0,表明是请求的包。 假设此时的序列号为seq=x(序列号不固定),即SYN=1、ACK=0、seq=x 这个包称为SYN包,当客户端发送完SYN包后,客户端就会进入SYN_SENT状态。 (2)B服务器收到数据包后发现SYN=1、ACK=0,知道这是TCP连接的请求包, 如果B确认与A建立TCP连接,那么B需要回复A。SYN=1、ACK=1、ack=x+1、seq=y(服务器的序列号)。 注意: 区分ACK和ack,小写ack是TCP中的确认号,是等待发送方发送下个数据包的起始字节,大写的ACK是占用一个比特位的ACK,确认是收到了SYN包。,服务器发送完ACK后进入SYN_REV状态。 (3)当A收到B的回复报文后,发现里面的SYN=1、ACK=1,于是也会想B回复一个ACK包,回复,,SYN=0、ACK=1、seq=x+1、ack=y+1,SYN=0、ACK=1表示这不是建立连接的请求包,而是回复包。A发送完成后,就进入ESTABLISHED,表示连接在A这端已经建立完成了。 (4)B最终收到A得ACK之后,也将进入ESTABLISHED,到此,TCP连接建立完成。
A最后回复一个ACK包是为了避免无效连接请求再次重生的问题。因为A首先发送SYN包之后,由于多种原因,导致很长一段时间都没被B接受到,于是A超市之后会重传这个包,于是网络上有两个SYN包,如果B收到了其中一个SYN包,并与这个SYN包建立连接,当数据传输完成后,tcp连接释放后,如果此时另一个连接SYN包突然被B接受到,B会认为A又在建立TCP连接,如果B在回复之后就立即建立TCP连接而不等待A的回复,name基于这个SYN包就会再次建立一个TCP连接,但这个连接并不是A想要建立的,如果要求A发送ACK包就可以避免这个问题,因为A知道这不是它想要建立的连接。 ———————————————— 版权声明:本文为CSDN博主「总教头。」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 |