不需要重发的数据用UDP发送更高效
TCP的工作方式十分复杂,如果我们能够理解TCP为什么要设计得如此复杂,也就能够理解UDP了。
为什么要设计得如此复杂呢?因为需要将数据高效且可靠地发送给对方。为了实现可靠性,需要确认对方是否收到了我们发送的数据,如果没有还需要再发一遍。
要实现上面的要求,最简单的方法是数据全部发送完毕之后让接收方返回一个接收确认。这样一来,如果没收到直接全部重新发送一遍,根本不用像TCP一样要管理发送和确认的进度。但是,如果漏掉了一个包就要全部重发一遍,怎么看都很低效。为了实现高效的传输,我们要避免重发已经送达的包,而是只重发那些出错的或者未送达的包。TCP之所以复杂,就是因为要实现这一点。
在某种情况下,即便没有TCP这样复杂的机制,也能够高效地重发数据,这种情况下数据很短,用一个包就能装下。如果只有一个包,就不用考虑哪个包未送达了,因为全部重发也只不过是重发一个包而已,这种情况下就不需要TCP这样复杂的机制了。如果不使用TCP,也不需要发送那些用来建立和断开连接的控制包了。
UDP没有TCP的接收确认、窗口等机制,在收发数据之前也不需要交换控制信息,也就不需要建立和断开连接的步骤,只要在从应用程序获取的数据前面加上UDP头部,然后交给IP进行发送就可以了。
接收也很简单,只要根据IP头部中的接收方和发送方IP地址,以及UDP头部中的接收方和发送方端口号,找到相应的套接字并将数据交给相应的应用程序就可以了。
另外,UDP协议没有其他功能了,遇到错误或者丢包一概不管。因为UDP只负责单纯地发送包而已,并不像TCP一样会对包的送达状态进行监控,所以协议栈也不知道有没有发生错误。但这样并不会引发什么问题,因此出错时就收不到来自对方的回复,应用程序会注意到这个问题,并重新发送一遍数据。
UDP头部UDP可发送的数据最大长度为IP包的最大长度减去IP头部和UDP头部的长度。这个长度与MTU、MSS不是一个层面上的概念。MTU和MSS基于以太网和通信线路上网络包的最大长度来计算的。
IP包的最大长度是由IP头部中的“全长”字段决定的。“全长”字段的长度为16比特,因此从IP协议规范来看,IP包的最大长度为65 535字节,再减去IP头部和UDP头部的长度,就是UDP协议所能发送的数据最大长度。如果不考虑可选字段的话,一般来说IP头部为20字节,UDP头部为8字节,因此UDP的最大数据长度为65 507字节。当然,这么长的数据已经超过了以太网和通信线路的最大传输长度,因此需要让IP模块使用分片功能拆分之后再传输。
本文摘取自周自恒翻译的户根勤编写的《网络是怎样连接的》
网友评论