传输层概述

网络层为我们提供了从主机到主机的传输能力,这种传输我们称为 点到点 传输。借助网络层,网络中的一台主机,可以向其他任一主机发送数据。

图中有两台主机,左边是一台普通的 PC ,右边是一台服务器,这是一种可以提供网络服务的主机。为访问服务器提供的网络服务,PC 必须与服务器进行通信。

通过网络层协议,例如 IP 协议,PC 与服务器都可以向对方发送数据。如果 PC 和服务器都只运行一个应用程序,那么网络层可以工作得很好。但这是不可能的!

进程间通信

无论是普通主机还是服务器,一般都不止运行一个应用进程。我们举个例子:

  • 服务器上可能运行着多个服务进程,包括:授时服务、直播服务等等;
  • PC 上也可能运行着多个应用进程,包括:校时工具、视频播放器等等;

为了观看直播,PC 上的播放器进程必须和服务器上的直播服务进程进行通信;为了校正时间,PC 上的时间同步进程必须和服务器上的时间服务进程进行通信。

换言之,我们需要一种 从进程到进程 的传输能力。

端口

那么,如何实现从进程到进程的传输能力呢?其实很简单,我们可以在网络层的基础之上,引入新的传输层,专注于进程间通信。

传输层的通信单元一般叫做 segment ),也分为头部和数据两个部分。其中,头部会保存发送进程和接收进程等相关信息。那么,保存进程的什么信息好呢?

你可能会想到进程号,但进程号其实不是一个好选择:一方面,进程号类型和数值范围都没有标准,可能因操作系统而有所差异;另一方面,进程号可能会变。

如果服务端进程发生重启,它的进程号就会发生改变。这时所有客户端都要进行调整,以便向新的进程号发送数据,显然是不合理的。

实际上,传输层引入了 端口port )的概念,用来区分不同的通信端点。如果将主机想象成一栋建筑物,那端口就是它上面的房间门:

一台主机上可以有很多个通信端口,应用进程可以关联到一个或多个端口。当进程需要发送数据时,它必须申请一个端口,数据从该端口发送出去;当某个端口有数据到达时,操作系统负责将数据提交给对应的应用进程。

这种从进程到进程的传输能力,可以叫做 端到端 传输。

我们可以通过主机地址,比如 IP 地址,来确定一个 ,主机地址加上端口,则可以确定一个

点到点 端到端
从主机到主机 从进程到进程
地址 <==> 地址 地址:端口 <==> 地址:端口

至于端口号,一般可以根据自己需要,灵活选用。但为了方便沟通协作,也形成了一些约定俗成的惯例,比如 Web 服务一般用 80 或 443 端口,邮件传输服务一般用 25 端口。这就是所谓的 知名端口

服务 端口
FTP文件传输 20 、 21
SSH安全远程登录 22
SMTP邮件传输 25
DNS域名系统 53
Web 80 、 443

通信过程

传输层的通信单元是 segment ),它负责封装数据和通信双方的端口号。

段需要借助网络层提供的点对点通信能力,由网络层包(比如 IP 包)携带,传输到目标主机。当段到到目标主机后,操作系统可以根据端口号,将数据提交给对应的进程。

以时间同步进程请求时间服务为例,通信过程大致如下:

  1. 时间同步进程需要向服务进程发请求数据,它先申请了一个端口,并通过该端口将数据提交给操作系统。
  2. 操作系统将数据封装成一个段,段的头部会包含双方的端口号。这个段需要先发给服务器,服务器收到后根据端口号即可将数据提交给对应的进程。
  3. 由于 IP 等网络层协议已经具备了主机间通信能力,因此可以将这个段搭载在网络层包中,发给服务器。网络层包需要经过若干条路由的转发,才能最终到到服务器。此外,网络层包每次转发时,都需要搭载在数据链路层帧中,发给下一节点。
  4. 网络层包来到服务器,服务器根据包头部中的协议字段,将承载在包数据中的段取出,提交给传输层来处理。
  5. 传输层收到这个段后,根据端口号,找到目标进程。
  6. 操作系统将段中的数据,提交给对应的时间服务进程。

在现行的 TCP/IP 协议栈中,有两个常用的传输层协议:

  • UDP ,无连接的数据报式协议;
  • TCP ,面向连接的流式协议;

下一小节,我们开始学习 UDP 协议。

小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注:

【小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注: