北京哪个医院可以治疗白癜风 http://baidianfeng.39.net/作者
我不想种地
责编
屠敏
近期工作,跟网络协议相关,这让我有机会更深入学习网络协议,而之前很长一段时间,我对网络协议的理解都停留在比较浅的层面。
比如:TCP是面向连接的、可靠传输,而UDP是非连接的、不可靠传输,TCP建连需要3次握手,会造成delay,UDP更快。
比如:socket编程,服务器socketcreate、bind、listen、accept、read/write、shutdown/close,客户端socketcreate、connect、read/write、shutdown/close,再加上epoll/select这几下子。
再比如:我知道网络编程要忽视SIGPIPE信号不然会挂,read返回0代表对端主动关闭,非阻塞的read要放在循环里要考虑返回值,多路复用以及阻塞、非阻塞的区别。
TCP/UDP的区别上,我是这样理解的:从北京到杭州,TCP相当于修了一条高铁线路(建连)再通车发货(传输数据),而UDP相当于寄快递,丢了不管(直接传输数据)。
上面的理解对不对?可以说对,也可以说不对。对于应用程序员来说,有了上面的认识+熟悉socket编程接口,够了吗?不够吗?
大物理学家费曼提出一个高效的费曼学习法,即从问题入手,试着把问题都讲出来,以教代学,一旦你能把问题都讲清楚,便学会了。所以我想尝试一下把TCP/IP讲清楚,借此让自己学明白,顺便帮助一下读者。
虽然《TCP/IP详解卷1》是一本关于互联网协议族很严谨详尽的书,但在我看来,它稍微有点晦涩,可能需要读几遍,才能心领神会。虽然我没有能力把这个问题说的更好,但因为我经历过从稀里糊涂到稍有所悟的过程,这可能是大师不可比的,我将尽量用通俗易懂的语言把TCP/IP相关的知识讲清楚。
TCP/IP是什么
TCP/IP协议族是一组协议的集合,也叫互联网协议族,用来实现互联网上主机之间的相互通信。TCP和IP只是其中的2个协议,也是很重要的2个协议,所以用TCP/IP来命名这个互联网协议族,实际上,它还包括其他协议,比如UDP、ICMP、IGMP、ARP/RARP等。
网络分层
大学《计算机网络》教科书上有经典的网络ISO七层模型,但七层划分太细了,稍显繁琐,不容易记住。
互联网协议族TCP/IP按粗粒度的四层划分,两种划分的对照图让彼此关系一目了然。
分层是计算机领域的常用技巧,比如互联网后端的三层架构“接入-逻辑-存储”就是分层思想的典型应用。
分层是为了隔离,通过分层划分职能,拆解问题,层与层之间约定接口,屏蔽实现细节。
TCP/IP自下到上划分为链路层、网络层、传输层、应用层。下层向上层提供能力,上层利用下层的能力提供更高的抽象。
链路层,也称网络接口层,包括操作系统的设备驱动程序和网卡,它们一起处理与传输媒介(光纤等)的物理接口细节。网络层,也就是IP层,负责处理IPdatagram在网络中的传输,IP层传输的是IPdatagram,借助路由表,把IPdatagram从网络的一端传输到另一端,简而言之:IP实现包的路由传输,IP协议和路由器工作在网络层。传输层,提供端到端之间的通信,包括提供面向连接和高可靠性的TCP,以及无连接不可靠的UDP。貌似TCP更好,但实际不是这样,UDP因为不需要建连开销,所以更快,应用得也很广,比如新一代互联网协议HTTP3就从TCP转向UDP,应根据适应场景选择传输层协议。应用层,跟应用相关,不同应用解决不同问题,需要不同的应用层协议。
链路层处理数据在媒介上的传输,以及主机与网卡、光纤等打交道的细节。因为与硬件相关,所以需要借助系统的驱动程序,链路层协议就是定义这些细节的,比如怎么把数据从网卡发送到光纤,采用什么格式编码等,它解决的数据在媒介上表示、流动的问题。
光有链路层功能肯定是不够的,网络上有成千上万的机器,主机A与B通信,你不能将数据发到主机C,所以仿照现实,要为主机分配网络地址,通过IP地址去标识网络中的一台主机,发送一个数据包,需要正确路由到目的地,这就好比你从家到公司,要经过哪些路径,需要地图,而路由表就类似这张地图。IP解决的是数据包在网络中的传输路由的问题。
有了网络层的传输路由能力,还不够,因为IP报在传输过程中可能丢包,比如中间经历过的路由器缓冲区满了便会丢包,这样不可靠,如果需要可靠传输的能力,便需要传输层基于IP层,提供更多的能力,TCP解决了可靠性问题。具体而言,如果丢包了,TCP层会负责超时重传,它通过接收确认和重传机制保证了可靠传输。另外,因为IP报都是独立路由的,所以从主机A到主机B,一份数据被拆分成x、y两个IP报先后发送,这2个包可能选择不同的传输路径,这样有可能y包先于x包到达,但我们希望在接收端(主机B)恢复这个数据的信息,但我们无法控制IP报的到达顺序,所以,我们需要在接收端恢复数据,我只需要在x、y包里记录它属于数据块的哪个部分,然后重组这份数据,这正是TCP做的,它会重新组装IP报,从而保证顺序性,递交给应用层。
有时候并不需要保证可靠性和顺序性,这便是UDP能提供的,它只是简单的把数据封装成IP报,然后通过IP层路由发送到目的端。
再往上,便是应用层协议了,比如