通过三次握手建立连接:
第一次握手:客户端向服务器发送连接请求
第二次握手:服务器接受连接后回复ACK报文,并为这次连接分配资源
第三次握手:客户端端接收到ACK报文后也向服务端发生ACK报文,并分配资源
为什么要进行三次握手才能确认连接建立了呢??
首先我们先了解三次握手是怎么处理异常的吧?
情景1:客户端向服务端发送请求,如果服务器没有接到接到请求怎么办呢?
那么客户端应该重发请求。
情景2:客户端向服务器发送请求,服务器接收到了客户端的请求,回复一个ACK报文。假设客户端没有接收到ACK报文,那怎么处理呢??
因为客户端一段时间后还没有接收到ACK回复,那么它就会重新发送连接请求。那么也就会导致服务器再次接收到客户端的连接请求,但是实质上服务器是之前已经接收到了,那么它也就知道自己发的ACK报文客户端并没有接收到(因为客户端如果接收到了就不会在发连接请求了,而是发送ACK报文了),那么它就会重新发送ACK报文给客户端。
情景3:经过一段时间后,客户端终于接收到服务端发过来的ACK报文,客户端回复服务端一个ACK报文,假设服务端没有接收到会怎样?
因为服务端没有接收到客户端的ACK报文,那么它就会重新发送ACK报文给客户端(这里有两种情况,第一种是接收到了请求,那么要判断是不是ACK报文,因为接收的可能是连接请求,如果不是ACK报文,说明还要重新发送。如果是ACK报文说明连接建立了。第二种是一段时间后还没有接收到请求,那么也要重新发送ACK报文),那么就会导致客户端再一次接收到ACK报文,因为又接收到了ACK报文说明服务端还没有接收到客户端发过去的ACK报文,那么客户端给服务端也要重新发送ACK报文了。直到一段时间后再也没有接到服务端的ACK报文为止。(如果没有接到就说明服务端已经接收到了ACK报文,也就是说服务端已经客户端资源已经准备好了,然后接下来就是要发送数据了)
之所以要三次握手是因为要三次握手才能处理建立连接中碰到的各种问题
发送数据 :
连接建立之后当然就是发送数据啦~注意除了客户端向服务器发送数据,服务器也要向客户端发送数据来保证客户端发送的数据服务器接收到的都是正确的。而且一般发送一部分数据后,服务端就返回一个数据,然后根据这个数据,判断之前发送的和服务器接收到的是不是一致的,如果是一致的,发送下一部分数据,如果不是一致的,重发本次数据。(之所以要发送一部分就要检验一次,是因为等发送完所有数据再检验,假设发送错了,那么代价太大了,而且数据越多,出错的几率越大~)
通过四次挥手断开连接:
四次挥手可以看成是两个二次挥手。
当客户端向服务器发送的数据已经发送完成了,那么客户端此时想服务端发送一个断开连接的请求。假设服务器接收到了断开请求,那么它立即回复一个ACK报文,如果客户端接收到了ACK,那么客户端就不在发送断开连接请求了,也就是开始等待(这里错误处理和三次握手差不多,也就不详细说明了)。
等到服务器把要想客户端发送的数据发送完成了,那么服务器会发送给客户端一个断开请求,假设客户端接收到了就服务端一个ACK报文,如果服务器接收到了ACK,那么连接就可以断开了。
那么为什么不用三次挥手而用四次挥手呢??
请注意在服务器接收到客户端的断开请求时,服务器向客户端发送的数据可能还没有发送完。如果是三次挥手的话,那么要等到服务器将数据发送完,再发送给客户端一个ACK,那么就麻烦了。因为客户端迟迟接收不到服务器的确认,那么就会不断地发送断开请求,这种情况使我们不希望出现的,因为对服务器和客户端都是一种不好的情况。但是如果是四次挥手的话,服务器一接收到断开请求,立即回复给客户端一个ACK,那么客户端接收到了ACK,就不会再发送断开请求了,只需等待到服务器发送完数据,然后通过一个服务器发送到客户端的断开请求来确认断开就ok了,那么上面出现的情况就完美解决了。