TCP中的三次握手和四次断开
TCP : 面向连接协议
面向连接:指的是通讯双方任何一方向对方发送数据前必须建立安全通道;
像打电话:拨打对方的电话号码必须等到对方的手机响铃,并且对方接收电话的时候才会通讯;
UDP:面向无连接协议
不是面向连接协议:双方通讯不需要事先和对方进行协商建立链接;也不管对方的ip地址和端口是否存在,就直接发送数据;
想发送短信:不管对方是否停机或者关机,只管发送信息,不管对方是否收到消息;
《1》
三次握手示意图
详解:
第一次握手:建立连接时,客户端发送SYN包(例如序列号SEQ=100)给服务器,进入了SYN_SEND 状态,等待服务器的确认;
第二次握手:服务器接收到SYN包之后,必须确认客户端,所以要发送ACK包(ACK=100+1),同时服务器还必须发送SYN包(序列号=300)等客户端的确认,此时,服务器端进入了SYN_RECV状态-。
第三次握手:客户端接受SYN+ACK包之后,向服务器发送确认包(ACK=300+1),该包发送完毕之后,此时客户端和服务器进入了ESTABLISHED,此时,完成三次握手,可以进行数据交换了。
《2》tcp关闭
由于tcp连接是全双工的====> 因此,每个方向都应该是单独进行关闭;
当host1 完成数据发送任务后就能够发送一个FIN来终止这个方向的连接。
一个tcp连接在收到一个FIN之后仍然能够发送数据;??
首先进行关闭的host1将主动执行关闭,而host2将会被动关闭。??
步骤过程如下:
TCP 关闭
详解:
(1)客户端发送数据完毕之后,发送一个FIN,提出断开连接要求;
(2)服务器接收到该FIN包后,对其作出响应,发送一个ACK包,确认这一方向的连接将关闭;
(3)服务器的应用程序做好关闭准备时候,服务器放方向发送一个FIN包给客户端,请求关闭连接请求;
(4)客户机对服务器发送的请求进行确认,并发送ACK包。
状态意义图表
问题:第四步为什么需要TIME_WAIT?
host1 发送ACK可能丢失并导致host2重新发送FIN消息,TIME_WAIT 维护连接状态;
(1)若是:执行主动关闭的一方host1不进入到TIME_WAIT状态关闭连接,当重传的FIN消息到达时,因为TCP已经不再有连接的信息了,所以就用RST(重新启动)消息应答,导致host2进入错误的状态而不是有序终止状态。如果发送最后ACK消息的一方处于TIME_WAIT状态并仍然记录着连接的信息,它就可以正确地响应对等方host2的FIN消息了。
(2)其次:TIME_WAIT 为连接中“离群的段”提供了网络中消失的时间,通常情况下,因为tcp仅仅丢弃该数据并响应RST消息,所以,这不会造成任何问题。当RST消息到达发出延时段主机时,因为该主机也没有记录连接的任何信息,所以它丢弃该段。然而,如果两个相同主机之间又建立了一个具有相同端口号的新连接,那么离群的段就可能被看成是新连接的,如果离群的段中数据的任何序列号恰恰在新连接的当前收窗口中,数据就会被重新接收,其结果是破坏新连接。(离群的段是什么意思???)
问题: tcp为什么需要三次握手,采用两次握手可以吗?
建立连接是在c/s的模式下,假设主机A是客户端,主机B是服务器端;
(1)tcp的三次握手过程:A向B发送连接请求,B收到A的报文段并确认,A再次对B的确认进行确认。
(2)三次握手为了:防止失效的链接请求报文段突然又传送到主机B,因而产生错误。
失效的连接请求报文段:指A发出的连接请求没有收到B的确认,于是经过一段时间后,A又重新向B发送连接请求,且建立成功,顺序完成数据传输。考虑到这种情况,A第一次发送连接请求并没有丢失,而是因为网络节点导致延迟到达B,B以为A又发起的新连接,于是B同意连接,并向A发回确认,但是,此时A根本不会理会,主机B就一直在等待A发送数据,导致主机B的资源浪费.(这个过程第二次已经建立连接成功了)
若是采用2次握手不行,就会出现上面所显示的浪费资源情况;
问题:为什么建立连接是三次握手,而关闭连接确实4次握手?
因为服务端的LISTEN状态下的socket收到syn报文建立连接请求后,它可以把ack和syn(ack起应答作用,而syn起同步作用)放在一个报文里面发送。但关闭连接时候,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你未必马上回关闭socket,也即你可能还需要发送一些数据给对方之后再发送FIN报文给对方来表示同意现在可以关闭连接了,所以这里的ack访问和FIN报文多数情况下是分开发送的。