一.TCP三次握手建立连接过程
TCP是面向连接的协议,无论哪一方发送数据,都必须建立一条连接.
先来看6种TCP的位码(即tcp标志位):
1.SYN:建立联机;2.ACK:确认;3.PSH:传送;4.FIN:结束;5.RST:重置;
6.URG:紧急;
seq(Sequeuece number):顺序号码,发送方发出为了确认接受方回应ack=seq+1;
ack(Acknowledge number):确认号码,为了回应seq,等于ack=seq+1;
第一次握手:主机A发送位码SYN=1(主机A告诉主机B我们需要建立联机),随机产生seq=x(随机数)的数据包到服务器,主机B由SYN=1知道A要求建立联机;
第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),SYN=1(主机B回应主机A,同意建立联机),ACK=1(确认我已经收到了),随机产生seq=y(随机数)的包.
第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq+1,以及ACK是否为1,若正确,主机A会再发送ack number=(主机B的seq+1), ACK=1,seq=t+1(顺序号码),主机B收到后确认seq与ACK,则建立成功;
最后客户端还要做一次确认是为了防止已失效的连接请求报文段又突然穿到了B,因而产生错误.
已失效的报文段:正常情况下:A发出连接请求,但因为丢失了,故而不能收到B的确认,于是A重新发出请求,然后收到确认建立连接,数据传输完毕后,释放连接,A发了2个,一个丢掉,一个到达,没有"已失效的报文段".
但是,在某些情况下,A的第一个在某个节点滞留了,延误了到达,本来这是一个早已失效的报文段,但是在A发送第二个,并且得到B的回应,建立连接之后,这个报文竟然到达了,于是B就认为,A又发送了一个建立连接的请求, 于是B就会发送确认报文段,同意建立连接,假若没有客户端的最后确认(第三次握手),那么这个连接就建立了起来,此时,A收到B的确认包,但A知道自己没有发送建立连接的请求,所以不会发送任何数据,而B却以为新的连接已经建立了,傻傻的等待着A给自己发数据,此时,B的资源就会被白白浪费,但是采用三次握手,由于B没有收到A的确认, 也就知道并没有建立连接,不会傻等着A给它发数据,三次握手避免了资源的浪费.
二.TCP四次撒手(断开连接)
建立一个连接需要三次握手,而终止一个连接要经过4次握手,这是由TCP 的半关闭造成的.因为TCP是全双工(即数据在两个方向上能同时传输),因此每个方向上传输完毕都要单独的关闭,当一方完成它的发送数据的任务后就发送一个FIN位码来终止这个方向的连接,当一端收到一个FIN之后,必须通知应用层另一端已经终止了那个方向的数据传送,发送FIN通常是应用层关闭的结果.如下图:B收到连接释放报文段后就立即发送确认,然后就进入了close-wait状态,此时TCP服务器就通知高层应用程序,因而A到B的连接就释放了,此时是"半关闭"状态, 也就是说A不可以给B发送数据,但是B可以给A发送数据.
此时,若B没有数据要发送给A了,其应用进程就通知TCP释放连接,然后发送给A连接释放报文段,并等待确认.
A发送确认后,进入time-wait,注意,此时TCP连接还没有释放掉,然后经过时间等待计时器设置的2MSL后,A才进入到close状态.
为什么要等待呢??
1.为了保证A发送的最后一个ACK确认报文段能够到达B,即最后这个确认报文段很有可能丢失,那么B会超时重传,然后A再一次确认,同时启动2MLS计时器,如此下去,如果没有等待时间,发送完确认报文段后就释放连接的话,B就无法重传了(连接已经被释放,任何数据都不能传输),就无法按照正常的步骤进入CLOSE状态,即必须收到确认后才能close.
2.防止" 已失效的连接请求报文段"出现在连接中,经过那2MSL,那些在这个连接持续的时间内,产生的所有报文段就可以从网络中消失,也就是说,在这个连接释放的过程中会有一些无效的报文段滞留在楼阁节点,但是呢,经过2 MSL这些无效的报文段就肯定可以发送到目的地,不会滞留在网络中,这样的话,在下一个连接中就不会出现上一个连接遗留下来的请求报文段了.
从左图可以看出:B结束TCP连接的时间比A早一些,因为B收到确认就断开了连接,而A还要等待2MSL.