赞
踩
前言:运输连接有三个阶段:连接建立、数据传送和释放连接
TCP为了实现可靠传输,发送方和接收方始终需要同步( SYNchronize )序号。 但是, 序号并不是从 0 开始的, 而是由发送方随机选择的初始序列号 ( Initial Sequence Number, ISN )开始 。 由于 TCP 是一个双向通信协议, 通信双方都有能力发送信息, 并接收响应。 因此, 通信双方都需要随机产生一个初始的序列号, 并且把这个起始值告诉对方。所以就需要通过多次发送数据报(握手)的方式,传达一些连接信息以及用来同步的序列号等
上图为TCP报文段的首部格式
TCP连接的建立采用客户服务器方式,主动发起建立连接的应用叫做客户(client),而被动等待连接的应用叫做服务器(server)
最初,两端的进程都处于CLOSED(关闭)状态,(本例子默认左边是发起连接的,即左边是客户端)
一开始,右边的TCP服务器进程先创建传输控制块TCB(存储每一个连接的一些重要信息),准备接收请求,然后加入LISTEN(收听)状态,等待请求‘
左边的TCP客户进程也先创建一个TCB,然后在打算建立连接时,向服务器发出连接请求报文,这时同步位SYN = 1,同时携带一个初始序号 seq = x (前面已经讲过序号都是随机的),在TCP规定中,SYN的报文段(即SYN = 1的报文段)不能携带数据,但是也需要消耗一个序号seq;发送完后,客户就进入SYN-SENT(同步已发送)的状态
服务器收到连接亲求的报文段后,如果同意建立连接,则向客户发送确认,在确认的报文段中,SYN = 1 ,ACK = 1;确认号ack = x + 1(因为在第一次握手的请求里面不携带数据,所以x + 1就是下一条报文段数据);且还要发送自己的一个初始序号seq = y,且这个和第一次握手一样,也不能携带数据,但是要消耗一个序号;这时服务器进入SYN-RCVD(同步收到)状态
客户收到服务器的确认后,还需要向服务器发送确认,报文段的ACK = 1;确认号ack = y+ 1,自己的序号seq = x + 1(等于第二次握手的ack);TCP连接已经建立,客户进入ESTABLISHED(已建立连接)状态,服务器收到后,也进入ESTABLISHED状态
可以;在服务器发送给客户的报文可以拆开为两端,即,先发送一个确认报文段,(ACK = 1,ack = x + 1),然后再发送一个同步报文段(SYN = 1;seq = y),这就变成了四次握手了,但是这样效果是一样的,所以就没必要了
不可以;
原因1:因为在客户发起请求时,如果客户的第一次请求出现了一些错误,如出现延迟这时客户就再发送一次,然后服务器收到了,然后做完交易了,也轻轻松松释放了连接;但是不巧的是,因为客户的一次连接亲求这个时候到了服务器了,但是服务器会认为你还是要发送亲求,如果这个时候只有两次握手,那么服务器这个时候就和客户建立了连接了,但是客户交易都做完了,所以压根就就理睬服务器了,但是服务器又一直在等,这样就造成了资源的浪费,所以一定需要第三次的再次确认,这样服务器因为没收到客户的再次请求,所以就不建立连接了;
原因2:如果没有第三次, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认,即服务器就收不到自己的确认号ack,这时在和客户进行交易时,压根就不知道自己需要发送的序号seq,但是因为为了实现可靠数据传输, TCP 协议的通信双方, 都必须要维护一个序列号, 以标识发送出去的数据包里面, 哪些是已经被对方收到的。 三次握手的过程即是客户与服务器的连接建立也是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
数据传输结束后,通信的双方都可以释放连接,且现在客户和服务器都处于ESTABLISHED状态
客户的进程先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭连接,客户把释放连接的报文段首部的终止控制位FIN = 1;且序号seq = u(等于客户前面发送的数据的最后一个字节的序号加1);然后客户进入FIN-WAIT-1(终止等待 1)状态,等待服务器的回复;FIN和SYN一样,即使不携带数据,也是需要消耗一个序号的;
服务器收到客户的连接释放亲求后,即发出确认,确认号ack = u + 1,而这个段自己的序号seq = v(等于服务器前面发送的数据的最后一个字节加1),然后服务器进入CLOSE-WAIT(关闭等待)状态;TCP服务器进程通知高层应用进程,所以客户到服务器的连接就释放了,这时的TCP处于半关闭(half-close)状态,即,你客户不能再发数据给我了,但是如果我服务器还要发数据,客户仍然需要接收,即服务器到客户的连接没有关闭,所以称为半关闭状态,且可能持续一段时间
客户在收到服务器的确认后,就进入FIN-WAIT-2(终止等待 2)状态,等待服务器发出释放连接的报文
如果服务器已经没有数据要发送给客户了,其应用进程就通知TCP释放连接,这时发出一个报文段且FIN = 1;自己的seq = w(在半关闭的状态可能又发送了一些数据,所以seq可能变了),且必须重复第二次挥手时的确认号ack = u + 1;这就服务器就进入了LAST-ACK(最后确认)状态了,等客户的确认
客户收到服务器的连接释放亲求报文段后,必须对次发出确认,将确认报文段的ACK = 1,确认号ack = w + 1;,而自己的序号seq = u + 1(因为前面发送的FIN报文段需要消耗一个序号);然后进入TIME-WAIT(时间等待)状态;在这里TCP的连接还没有释放掉,必须经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL后,客户才进入CLOSED状态,但服务器收到后,就进入CLOSED状态,不用等待
原因1:为了保证客户发送的最后一个ACK确认报文段能够到达服务器;因为如果服务器因为某些原因没有收到最后的确认报文段,这样服务器就无法正常进入CLOSED的状态了,在等待时间内,客户还可以重新发送,且重启时间等待计时器
原因2:防止在握手里面由于某些原因广域晚到的保温到出现在本连接里面,因为在2MSL的时间内,就可以使本连接持续的时间内所有产生的报文都消失在网络中
挥手至少需要4次,因为释放连接是单方面的发出释放请求,然后等待对方做出确认,即一方的释放连接请求,至少是两次挥手,所以加起来至少四次
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。