您的位置:首页 > 理论基础 > 计算机网络

TCP三次握手四次挥手

2016-05-18 13:22 337 查看
TCP报文段首部格式




TCP源端口(Source Port)和目的端口(Destination port):各占2个字节,分别写入源端口号和目的端口号。
TCP序号(序列码,Sequence Number):占4个字节,在TCP连接中传送的字节流中的每一个字节都按顺序编号首部中的序号字段值指本文段所发送的数据的第一个字节的序号。
TCP确认号:占4个字节,期望收到对方下一个报文段的第一个数据字节的序号。如果设置了ACK控制位,这个值表示一个准备接收的包的序列码。
TCP数据偏移(HLEN):占4位,包括TCP头大小,指示何处数据开始。
保留(Reserved):占6位,这些位必须是0。为了将来定义新的用途所保留。
标志(Code Bits):6位标志域。表示为:紧急标志、有意义的应答标志、推、重置连接标志、同步序列号标志、完成发送数据标志。按照顺序排列是:URG、ACK、PSH、RST、SYN、FIN。
窗口(Window):16位,发送本报文段的一方的接受窗口,窗口值告诉对方:从本报文段首段中的确认号算起,接收方目前允许对方发送的数据量。
校验和(Checksum):16位TCP头。源机器基于数据内容计算一个数值,收信息机要与源机器数值结果完全一样,从而证明数据的有效性。
紧急指针(Urgent Pointer):16位,指向后面是优先数据的字节,在URG标志设置了时才有效。如果URG标志没有被设置,紧急域作为填充。加快处理标示为紧急的数据段。
选项(Option):长度不定,但长度必须是一个字节。如果没有选项就表示这一个字节的域等于0。

注意 (A)不要将确认序号Ack与标志位中的ACK搞混了。
(B)确认方Ack=发起方Req+1,两端配对。

2.三次握手
客户端和服务端进程创建传输控制块TCB
(1)第一次:A向B发出连接请求报文段,此时同步位SYN=1,选择初始序号seq=n。TCP规定,SYN报文段不能携带数据,但要消耗一个序号。这时,TCP客户进程进入SYS—SENT(同步已发送)状态
(2)第二次:B收到连接请求后同意建立连接,向A发送确认,此时把SYN和ACK置为1,确认号ack=n+1,同时也为自己选择一个初始序列号seq=k。这个报文段不能携带数据,但要消耗一个序号。这时,TCP服务器进程进入SYS—RCVD(同步收到)状态。
(3)第三次:TCP客户进程收到B点确认后,还要向B给出确认。将ACK置1,确认号ack=k+1,自己的序号seq=n+1。TCP规定,ACK报文段可以携带数据,但如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是seq=n+1。这时,TCP已建立连接,A进入ESTABLISHED(已建立连接)状态。B收到A的确认后,也进入ESTABLISHED(已建立连接)状态



3.四次挥手
AB处于ESTABLISHED(已建立连接)状态。
(1)第一次:A的应用进程向其TCP发出连接释放报文段,并停止发送数据,主动关闭TCP连接。A把FIN置1,序号seq=x,它等于前面已传达过的数据的最后一个字节的序号加1。这时A进入FIN-WAIT-1(终止等待1)状态,等待B确认。TCP规定,FIN报文段即使不携带数据也要消耗一个序号。
(2)第二次:B收到连接释放报文段后发出确认,确认号是ack=x+1,自己的序号seq=y。B进入CLOSE-WAIT(关闭等待)状态。此时,A到B这个方向的连接就释放了,这时TCP处于半关闭状态,即A已经没有数据发送了,但B若发送数据,A仍要接收。
A收到B的确认后,进入FIN-WAIT-2(终止等待2)状态,等待B发出连接释放报文段。
(3)若B已经没有数据向A发送了,其应用进程通知TCP释放连接。B把FIN置1,序号seq=i,确认号seq=x+1。这时B进入LAST-ACK(最后确认)状态,等待B确认。
(4)A在收到B的连接释放报文后,必须对此发出确认。把ACK置1,确认号是ack=i+1,自己的序号seq=x+1。B进入TIME-WAIT(时间等待)状态。此时,TCP连接还没有释放,必须经过时间等待计时器设置的时间2MSL后,A才进入到CLOSE状态。当A撤销相应的传输控制块TCP后,就结束了这次的TCP连接。




4.主动发起关闭连接的操作的一方将达到TIME_WAIT状态,而且这个状态要保持Maximum Segment Lifetime的两倍时间。为什么要这样做而不是直接进入CLOSED状态?原因有二:
一、保证TCP协议的全双工连接能够可靠关闭
二、保证这次连接的重复数据段从网络中消失先说第一点,如果Client直接CLOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致Server没有收到Client最后回复的ACK。那么Server就会在超时之后继续发送FIN,此时由于Client已经CLOSED了,就找不到与重发的FIN对应的连接,最后Server就会收到RST而不是ACK,Server就会以为是连接错误把问题报告给高层。这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进入CLOSED,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。再说第二点,如果Client直接CLOSED,然后又再向Server发起一个新连接,我们不能保证这个新连接与刚关闭的连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达Server,由于新连接和老连接的端口号是一样的,又因为TCP协议判断不同连接的依据是socket pair,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。各种协议都是前人千锤百炼后得到的标准,规范。从细节中都能感受到精巧和严谨。每次深入都有同一个感觉,精妙。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  序列号