TCP是面向连接的,传输数据前要通过“三次握手”建立连接,传输完成后也要拆除连接,就像我们打完电话要挂断一样。
TCP通过“四次挥手”拆除连接。
假设电脑A发送数据给电脑B,电脑A已将全部数据发送完毕,则“四次挥手”过程为:
第一次挥手,电脑A发送拆除连接请求(FIN=1);
第二次挥手,电脑B收到请求后,需要做个收尾,比如缓冲区中还有数据没有处理完。为避免对端超时,发送ACK=1对电脑A的请求进行确认,意思是“你的请求我收到了,但我还没处理完,稍等一下下哦”;
第三次挥手,电脑B处理完成,收尾结束,向电脑A发送拆除连接请求(FIN=1),意思是“我OK了,可以拆除了”;
第四次挥手,电脑A收到后,向电脑B回复ACK=1,意思是“收到,可以拆除”。
电脑B收到第四次挥手报文后,立即拆除连接。电脑A发出第四次挥手报文后,经过2倍MSL时间后,拆除连接。
MSL(Maximum Segment Lifetime,最大报文段生存时间),不同操作系统默认值也不同。
Windows系统,MSL默认为120秒;
Linux系统,MSL默认为60秒。
既然是“默认”,那就可以改。怎么改就不在这儿说了,感兴趣的小伙伴自己查查。
电脑A为什么要等待2MAL时间,而不是发出第四次挥手后就立即拆除呢?
电脑A发出第四次挥手报文后,立即拆除连接。可是,如果这个报文丢失,电脑B就收不到了。电脑B迟迟收不到确认回复,经过RTO超时后会重传第三次挥手报文,然而,此时的电脑A已经拆除连接,不会再发ACK确认,而电脑B则会不停地超时重传,无法拆除连接!
当然,四次挥手是很佛系的正常拆除。实际上我们常常会遇到不正常拆除,比如断网了,或者把应用程序强行关闭了,等等。不正常拆除会通过RST拆除重连,或者通过TCP的保持计时器处理。
通信双方如果收到对方的任意报文,都会重置保持计时器。如果长时间没收到对端的消息,保持计时器超时后,会每隔75秒发送探测报文给对方,发送10次后还没有收到对方回复,则拆除连接。
TCP虽然保证了可靠传输,但是它也有缺点:一是数据传输要确认、要重传,速度很慢,不适合对延时比较敏感的应用,比如语音、视频等,流畅比可靠更重要;二是要先建立连接才能通信,不适合一对多、多对多的应用。
所以,传输层还需要一个速度快、简单的协议。它就是UDP(User Datagram Protocol,用户数据报协议)。
UDP没有TCP拥有的各种机制,是一种无连接的传输协议,所以传输数据非常快。
看看UDP的封装格式,太简单了!
源目端口号、校验和与TCP的含义一样。Lenth指整个数据段长度,包括data和UDP头部封装。
UDP把应用程序要发送的数据拿来,加上头部后就扔给IP了。啥也不管!连接?可靠?跟我UDP没关系。
由于没有连接,也就不需要维护状态,就可以把数据同时发给多个人!所以,UDP可以支持组播和广播。
TCP面向字节,所以TCP有MSS来保证数据段不被IP分片,减少IP工作量。而UDP是面向报文的,就是说应用程序要发多少,UDP只管加头部交给IP,不关心报文大小。大了,让IP去分片就好了。
UDP的应用非常多,比如视频网站、网络游戏、聊天软件、视频监控,等等。
小Q:既然UDP和IP一样,也是无连接、不可靠的,为什么应用程序不把数据直接交给IP呢?
欢迎留言讨论。