? ? ?日常我们网上冲浪,Email,软件聊天等,都是通过这两种协议来进行数据传输的。这两种协议是如何工作的,两者有什么区别呢?
两者最大的区别在于TCP协议是基于连接的,UDP协议是基于非连接的。
?TCP协议是如何让保证进程与进程之间的可靠传输的呢?
这个过程需要进行三次握手、传输确认、四次挥手才能完成。
三次握手
?为什么要采取3次握手,而不是2次握手机制呢?
? ? ?假设采取2次握手建立连接,客户端向服务端发送了一个SYN包,请求建立连接,因为某些未知的原因,并没有到达服务器,而是在网络的某个节点产生了滞留。为了建立连接,客户端会向服务重发一个SYN包,这次的数据包正常送达,服务端回复了SYN+ACK之后建立了连接。但是第一包数据包阻塞的网络节点,突然恢复,第一包SYN包发送到服务端,这是服务端会认为这是客户端又发起了了一个新的连接,从而在2次握手之后进入数据等待状态。服务端会认为是2个连接,而客户端认为是1个连接,造成状态不一致。
? ? ?如果是3次握手,服务端收不到最后的ACK包,自然不会成功建立连接。所以3次握手机制,从本质上来说,是为了解决网络信道不可靠的问题。为了解决在不可靠信道,建立起可靠连接。
经过3次握手之后,客户端和服务端都进入了数据传输状态。
上面提到,TCP机制需要在不可靠信道上建立起可靠连接,那如何能保证可靠连接呢?
想想实际应用场景下:
1、一个数据包需要拆分成几个数据包传输,如何处理丢包问题;
2、每个数据包到达顺序不同,如何处理乱序问题;
? ? 为了满足上述要求,TCP协议为每个连接,建立了一个发送缓冲区,从建立连接的第一个字节的序列号为0,后面每个字节的序列号就会增加1。在发送数据时,取一部分数据组成发送报文,在其TCP协议头会附带序列号和长度,接收端在收到报文后,需要回复报文,确认报文中的ACK,等于接收序列号和长度,也就是下一包发送的起始序列号。通过这样一问一答的方式,能够确认发送端发送的数据已经被接收端接收到。发送端也可以一次发送连续的多包数据,接收端只需要回复一次ACK确认即可。这样,发送端可以把待发送的数据分割成一系列的碎片,发送到对端,对端更具序列号和长度,对端根据序列号和长度重构数据,假设其中丢失了某些数据包,接收端可以要求发送端重传,假设丢失了100-199这100个字节,接收端向发送端发送ACK=100报文,发送端接收到报文后重传这一组数据,接收端收到后进行补齐,以上过程不区分客户端和服务端,TCP是全双工的,对于两端来说均采用上述机制。
四次挥手
? ? ? 对于连接的客户端和服务端,均可发起关闭连接,这个过程需要4次挥手来完成连接关闭。
? ? ? 假设客户端主动发起关闭请求,他需要向服务端发起一个FIN包,表示要发起关闭连接,服务端发送一个ACK包,表示自己发起关闭等待状态,这是第一次挥手,客户端进入终止等待状态,这是第二次挥手,服务端此时还可以发送未发送的数据,客户端还可以接收数据,待服务端发送完数据,就发送一个FIN包,进入最后确认状态,这是第三次挥手,客服端收到后回复一个ACK包,进入超市等待状态,经过超时时间后关闭连接。而服务端收到ACK包后立即关闭连接。这是第四次挥手。为什么客户端需要等待超时时间,这是保证对方已收到ACK包,送完最后一个ACK包后就释放了连接。一旦ACK包在网络中丢失,服务端将一直处于最后确认状态。如果客户端发送了最后一个ACK包后,等待一段时间后,服务端没有收到ACK包,服务端会重发FIN包,客户端会回应这个FIN包,重发FIN包或刷新超时时间。这个和三次握手机制一样,为了在不可靠的网络中进行关闭确认。
|