TCP--三次握手

  我们再说TCP的时候经常会说他是有连接的,可靠的,面向数据流的三个特点,今天我们就来介绍一下TCP的有连接的。

  先说一下什么是面向连接的,我们在创建TCP连接的时候和UDP不一样,我们得先向客户端发送请求,然后客户端回复我们一个确认应答和请求,之后我们再给客户端发送确认应答,也就是经典的三次握手,这时候双方才可以发送数据,UDP不管你有没有连接,上来就直接发,这就好比我们TCP用的是手机来发短信,当小蓝想给小红聊天的时候就给小红发短信,小红在吗我是小蓝我想和你聊天,这时候小蓝不是这条短信有没有发到,他不知道自己手机是不是欠费了,他就得等着小红的回应,当小红收到信息之后,会明白,哦小蓝想和我聊天,那我的手机收短信没问题的,我回复他一个:我是小红我收到了,你能看到我的消息吗?这时候小红清楚自己能够收短信,但是不知道自己能不能发啊,等会小蓝看到了小红的回信,这时候小蓝清楚了,我的发送功能没问题,发送出去了,小红看到了,并且我的接受也没问题,小红给我的回信我也接受到了,但是小红现在还在等着啊,他不知道自己是不是成功发出来消息了,这时候小蓝再回复小红一个,没问题我能看到你的消息,当小红收到的时候那这时候双方都能清楚自己收发功能都没问题,这时候双方就可以开始正式发送消息了。

  这就我们TCP链接的过程,把小蓝变成客户端,小红变成服务端就可以了。这个过程也就是我们TCP大名鼎鼎的三次握手。

  

第一次握手:当我们的客户端想和服务端传输数据的时候,就会向服务端发送我们的连接请求报文,也就是把报文段里边的SYN位置设置为1,然后客户端就会进入SYN_SEND状态,然后等待服务端的确认消息。并且这时候会把报头里边的Seq也就是序列号设置成一个操作系统随机生成的一个数字X

第二次握手:当服务端接收到我们客户端发来的SYN报文段之后,就需要对我这个SYN请求做出回答, 然后会把报头里边的ACK设置为1,并且还要把确认序号设置为刚刚发送Seq中的X+1,并且同时,自己还要发送一个SYN请求给客户端,并将SYN的值变成1,然后Seq设置为操作系统随机生成的一个Y,然后服务端把上边的数据发送出去,这时候服务端变成SYN_RECV状态。

第三次握手:当客户端收到服务端发来的报文的时候,会把ACK中的值设置成刚刚生成的Y+1,然后Seq设置为X+1和第二次握手中的值是一样的,然后发送给服务端,当这个数据包发送完毕值,客户端和服务端都会进入ESTABLISHED状态,这时候就完成饿了三次握手。

 

  为什么要有三次握手?

  1. 三次握手的目的是为了方式已经失效的链接请求报文团又发送给了服务端,从而产生了错误。比如现在我们的客户端发送了一个请求包,说服务端那我想和你建立链接,但是这个数据包在网络里边发送延迟了,客户端都放弃了,算了现在网卡我先不建立连接了我先关掉吧,但是等了一会,服务端接受到了消息,看到了这个请求,如果没有三次握手,那么服务端看到这个请求之后链接就建立起来了,就开始往客户端发送包,但是客户端不会理你,这时候服务端很多资源就浪费掉了,但是有三次握手的话,服务端接受到之后会向客户端发送确认,如果客户端没有确认,服务端也不会建立链接的。

  2. 还有就是我上边说到的例子,存在一种情况我们的客户端或者服务端的发送或者接受工功能损坏了,如果客户端和服务端三次握手成功了,就说明客户端和服务端的发送和接受功能都是正常的,那么这个时候就可以发送数据了。

  3. 并且这里的情况和我们上次说的可靠是相呼应的,一个请求一个应答,来保证可靠。

  4. 为什么不能是两次,这里要想一种情况,假如现在你要和班里的小女生传纸条,如果采用两次握手,也就是说,假如现在你给他扔了一个小纸条,聊天吗?他没捡到,然后你又扔了一个聊天吗?他收到了,他说好,这时候你们聊天了,聊完之后收不聊了俩人开始上课了,但是这时候突然小女生捡到了你第一次扔的那个聊天吗?她捡到了,然后给你回了一个聊,这就算两次握手完成了,这时候 他再跟你扔小纸条你就收不到了,所以这种 情况下两次握手会浪费很多资源。

   那假如说在握手过程中发生了中断怎么办?

  1. 如果说在第一次握手发出的时候数据包发生了中断,也就是说A发送给B的SYN丢失了,A会进行超时重传,直到B收到了A的请求

  2. 如果说第二次握手的ACK和SYN发生了中断,那么B也是会不断的进行超时重传的。一直到B收到了A的确认响应,说明A收到了这个数据包

  3. 如果A发给B的第三次握手中断了,东西丢了A不会重新发送,超时后B会再次给A发送SYN信号,也就是回到了第二次握手,直到B收到了A的这个第三次握手。