计算机网络运输层之多路复用与多路分解

---------------------------------------------------------------
1、什么是多路复用和多路分解
咱们知道,在网络上主机与主机之间的通讯,实质上是主机上运行的应用进程之间的通讯。例如,当你经过Http上网浏览网页时,实质上是你所访问的主机的服务器进程与你本机的浏览器进程在进行通讯。试想一下,当你在上网的同时,还挂着QQ,还使用ftp下载大文件,这时就有三个网络上的进程与你的主机上的三个进程进行通讯,那么系统是怎么样正确地把接收到的数据定位到指定的进程中的呢?也就是说,系统是怎么把从ftp服务器发送过来的数据交付到ftp客户端,而不把这些数据交付到你的QQ上的呢?反过来考虑,系统又是如何精确地把来自各个应用进程的数据发到网络上指定上的主机(服务器)上的对应进程的呢?这就是多路分解与多路复用的做用了。
 
为了说明这个问题,先来补充一下操做系统方面的知识,以Linux对文件和设备的管理和使用方式为例。
 
为了方便资源的使用,提升机器的性能、利用率和稳定性等等缘由,咱们的计算机都有一层软件叫作操做系统,它用于帮咱们管理计算机可使用的资源,当咱们的程序要使用一个资源的时候,能够向操做系统申请,再由操做系统为咱们的程序分配和管理资源。一般当咱们要访问一个内核设备或文件时,程序能够调用系统函数,系统就会为咱们打开设备或文件,而后返回一个文件描述符fd(或称为ID,是一个整数),咱们要访问该设备或文件,只能经过该文件描述符。能够认为该编号对应着打开的文件或设备。
 
而当咱们的程序要使用网络时,要使用到对应的操做系统内核的操做和网卡设备,因此咱们能够向操做系统申请,而后系统会为咱们建立一个套接字Socket,并返回这个Socket的ID,之后咱们的程序要使用网络资源,只要向这个Socket的编号ID操做便可。而咱们的每个网络通讯的进程至少对应着一个Socket。向Socket的ID中写数据,至关于向网络发送数据,向Socket中读数据,至关于接收数据。并且这些套接字都有惟一标识符——端口号。
 
有了上面的了解后,再来讲说什么是多路分解和多路复用。
 
每一个运输层的报文段中设置了几个字段,包括源端口号和目的端口号等。多路分解就是,在接收端,运输层检查这些字段并标识出接收套接字,而后将该报文定向到该套接字。其工做方式能够简单地认为是这样的,主机上的每一个每一个套接字被分配一个端口号,当报文到达主机时,运输层检查报文段中的目的端口号,并将其定向到相应的套接字。
 
多路复用就是从源主机的不一样套接字中收集数据块,并为每一个数据块封装上首部信息从而生成报文段,而后将报文段传递到网络层中去。
 
2、无链接的多路复用和多路分解
在运输层,无链接的网络传输是经过UDP来实现的。UDP报文中只有源端口号和目的端口号,一个UDP套接字是由一个含有目的IP地址和目的端口号的二元组来全面标识的。在客户端,源端口号是客户进程套接字的端口号,目的端口号是服务器的端口号。而在服务器端,源端口号是服务器的建立的套接字的端口号,而目的端口号是客户端的套接字的端口号。
 
例如主机A产生了一个UDP报文段,报文段中就会包括源端口号(11111)、目的端口号(22222)、程序数据(还有两个其余的值,在这里咱们不关心)。而后,运输层将生成的报文段交给网络层。网络层将其放到一个IP数据报中,并提供尽力而为的交付,将其发送到主机B中。若是该报文到达主机B,主机B运输层就会检查该报文的端口号,并将该报文段传递给套接字的端口号为接收到的报文段的目的端口号(22222)的套接字。从而实现了进程间的网络通讯。而源端口号的做用是为了让主机B能向主机A发送信息的,也就是说,当主机B在接收到主机A的数据后,要向主机A发送一个回应时,主机B发送的报文段的目的端口号就是11111.
 
注意:咱们看到使用UDP来传输报文段时,一个UDP套接字是由一个含有目的IP地址和目的端口号的二元组来全面标识的。所以,若是两个UDP报文段有不一样的源IP地址和源端口,但具备相同的IP地址和目的端口号,那么这两个报文段将经过相同的目的端口号定向到相同的目的进程。这里没有过多地说明IP地址,是由于IP地址是网络层的知识,因此没有说起,咱们如今只须知道,IP地址对应着一台主机,而端口号对应着一台主机上的一个进程(或套接字)。
 
3、面向链接的多路复用和多路分解
从上面的解说中,咱们能够知道,网络上主机间的进程间通讯,实质上是经过套接字来实现的。在运输层中面向链接的网络传输多使用TCP,而TCP套接字和UDP套接字之间有一个细微的差异,就是,TCP套接字是由一个四元组(源IP地址、源端口号,目的IP地址,目的端口号)来标识的。这样,当一个TCP报文段从网络到达一台主机时,主机会使用所有4个值来将报文段定向,即多路分解到相应的套接字。
 
与UDP不一样的是,两个具备不一样源IP或源端口号的到达的TCP报文段将被重定向到两个不一样的套接字。
 
尽管如此,而TCP的多路利用和多路分解的工做原理与无链接的UDP的多路复用和多路分解的原理仍是大体同样的。
 
想一想为何TCP的多路复用和多路分解要这样设计呢?我的认为,这是由于TCP和UDP对待接收到的数据的处理方式不一样所致的。咱们以服务器上的TCP套接字和UDP套接字为例,假定服务器接收客户端的数据,并把数据发送回客户端。
 
当一个UDP服务器接收到一个UDP报文段时,它会根据收到的UDP报文段的源IP和源端口号,把数据发送回客户端,它并不须要建立一个新的套接字来处理该报文段;
 
而对于一个TCP服务器,当它接受一个链接时,它会产生一个新的套接字,而后经过新的套接字来与客户端通讯,也就是经过新的套接字来把数据发送回给客户端。因为每个链接都会产生一个新的套接字,因此具备不一样的源IP或源端口号的链接就是一个不一样的链接,对应着产生的新的不一样的套接字。
 
试想一下,若是TCP套接字也是使用像UDP那样的只用源端口号和目的端口号来彻底标识一个套接字,那么当客户机A有一个Http链接时,该TCP报文的目的端口号为80,目的IP地址为TCP服务的IP地址。TCP服务器产生一个新的套接字来处理该请求,此时,客户机B又有一个Http链接,TCP报文的目的端口号也为80,目的IP地址也为TCP服务的IP地址。而TCP套接字也是使用像UDP那样,两个具备不一样的源Ip或源端口号但具备相同目的IP和目的端口的报文段定位到同一个套接字中,那么这个客户机B的TCP报文段则会多路分解到客户机A的套接字上,而该套接字并不该该被客户机B的Http链接使用。
 
PS:若是对于这个解说不太明白,能够看看本人写的一个用TCP和UDP进行通讯的小例子,
相关文章
相关标签/搜索