计算机网络:应用层协议原理

前情提要

系统地学习计算机基础知识,并用博客记录下来。我们的教材是 《计算机网络-自顶向下方法(第7版)》,中科大郑烇、杨坚全套《计算机网络》

计算机网络:Internet基本原理(上)

计算机网络:Internet基本原理(下)

今天来看看计算机网络第二章应用层协议原理。

网络应用的体系结构

按照应用进程和应用进程的沟通方式来看,可以把网络应用进程分为两类。

  • CS 模式:客户-服务器(C/S: client/ server)
  • 对等模式(P2P: Peer To Peer)

CS 模式

什么是 CS 模式呢?

  • 服务器先运行,守候在一个约定好的知名端口上。
  • 客户端后跑起来,主动请求服务器的资源。
  • 服务器响应资源,把资源返回回来。
  • 客户端得到这样一个资源,整个的过程就结束了。

服务器

  • 一直运行

  • 固定的IP地址和周知的端口号(约定)

    • 需要运行在知名端口上(比如? 80),这样客户端才能找到它。
  • 扩展性比较差,需要建立起服务器农场才能维持很大的并发。

    • 数据中心进行扩展
    • 扩展性差。请求到达一定阈值之后,性能是断崖式地下跌。

?

  • 当来了一个请求,服务器需要从硬盘读数据,处理数据,再通过网络把数据打出去。
  • 而当服务能力达到一定门限的时候,不管是它的网络出口,还是网络本身,还有它自己的服务能力,其中任务一个环节,都可能都会存在瓶颈。请求到达一定阈值之后,它的性能是断崖式地下跌。

客户端

  • 主动与服务器通信

  • 与互联网有间歇性的连接

  • 可能是动态 IP 地址

    • ? 例如我们的笔记本电脑,通过 wifi 来接入互联网。然后这个网络会给我们采用 dhcp 的协议,动态的给我们一个地址。
    • 但是服务器的地址是不能动的,因为客户端要通过 IP 地址查找服务器。
  • 不直接与其它客户端通信

P2P 系统

因为 CS 模式有扩展性差的问题,所以 p2p 系统应运而生。

p2p 系统我们前面也说过了juejin.cn/post/699391…

所以说,随着系统节点数量的增加,请求节点的数量也在增加,但是提供服务的节点的数量也在增加。这样的话,就能够很容易地平滑扩展。比如迅雷就是用的 P2P 系统,实现文件快速下载。

但 P2P 也有它的问题,管理起来非常困难。为什么呢?每个节点会上线、会下线,而每个节点只有在上线的时候才能提供服务。

所以说,上线的时候我要追踪到你上线了,下线的时候你也要通知到我。

混合体

当然还有混合体,比如 Napster 是一种 p2p 的文件分发系统。它是美国西北大学一个本科生开发的,用于在校园网中分发免费的 MP3 音乐。

它的工作原理是什么呢?

注册、目录查询是 CS 的,文件下载是 P2P 的。

  • 你下载了 Napster 的客户端,运行起来之后,你就成为了一个节点。这个时候,Napster 会向服务器发出一个注册的命令,告诉服务器你的 IP,还有你拥有的 MP3 音乐。
  • 如果你想下载其他音乐,客户端会向中心服务器联系,找到哪些节点有这个音乐可以供你下载。

对于大学生来说是非常有吸引力的。只要下载这个软件,就可以收获一堆免费的音乐,有一阵大学 2/3 的带宽都用于 P2P 的分发。

但唱片厂商少收了很多钱,最终把 Napster 告上了法院,Napster 也被迫下架了。

但这种技术形式非常好,用户下载的速度比较快,资源也比较多。而且随着用户数量越多,资源越多,下载的速度越快,吸引更多的用户进来,形成马太效应。

? 当然除了国外的 Napster,国内的也有应用采用这种系统,比如百度网盘、迅雷。

进程通信

只有应用进程之间能够发送和接收 message 报文,我们才能够实现各种各样的网络应用。所以,本质上来说,我们需要网络提供远程的应用、进程之间的通讯。

那么如果两个应用进程在一台机器上,在同一个主机内,他们之间可以直接借助操作系统本身提供的方式来进行,比如管道、消息队列,还有共享缓冲区等等。

不同主机

但是如果一个进程跑在一台设备上,一个进程跑在另外一台联网的终端设备上。他们之间要通信,就要符合相应的规范了。

好,我们来看一下具体是怎么样做的。

首先发起通信的这个进程,叫客户端。进行响应客户端的这种请求,叫服务器。注意:P2P 架构的应用也有客户端进程和服务器进程之分哦,每个 Peer 既可以是客户端,也可以是服务器。

分布式进程通信需要解决的问题

  • 问题1:进程标示和寻址问题(服务用户)

    • 也就是说,应用进程要标识自己,从而让别人能够找得到他。
    • ? 比如你从淘宝上买了货物,你需要留给商家姓名、电话、地址,这样他才能够把货物?发送给你。
    • 所谓的标识,就是用一个标志位来表示自己是唯一的,能够跟其他所有人能够区分。同时,这个标识要具备寻址的作用。
  • 问题2:传输层-应用层提供服务是如何(服务)

    • 也就是说,应用通过层间接口,必须借助于传输层提供的服务,才能向对方发送报文。那么,我们的问题是下层所提供的服务形式是什么?下层提供的服务在哪里?

    • ? 比如你把货物交给货运公司,他要告诉你在哪里交货物、送货的形式是什么。

    • 也就是形式和服务两个问题,后面我们会一一解答。

      • 位置:层间界面的服务访问点 SAP,具体是 TCP/IP: socket。
      • 形式:应用程序接口 API,具体是 TCP/IP 的 socket API。
  • 问题3:如何使用传输层提供的服务,实现应用进程之间的报文交换,实现应用(用户使用服务)

    • 怎样定义应用报文的格式和相应的解释。我收到报文的时候,应该做出什么样的动作?
    • 那这样的话,两个应用进程才能够按照相应的协议动作来实现协议行为,从而实现各种各样的网络应用

好,那我们来看一下怎么样解决问题。

问题 1:对进程进行编址( addressing)

在 tcp ip 协议栈当中,应用进程的标识和寻址包括了几个部分。

  • 第一个,主机 IP。你在哪个 IP 上?你在哪个终端设备上,你的 IP 是什么?
  • 第二个,TCP 还是 UDP。你的应用进程是在 TCP 上跑还是在 UDP 上跑?
  • 第三个,端口号。在 TCP 上有好多应用进程,你在哪个端口呢?

这样才能区分出一个进程。

我们应该了解一些的默认的端口号——如果不指明对方端口,就使用这个协议所对应的默认端口。比如在 TCP 上, HTTP 默认端口号是 80 号, ftp 是 21。

我们把一个 IP 上的 TCP 上的某个端口称之为端节点,所以,任何一个应用进程之间的任何一对应用进程之间的通信,都可以用两个端点来表示,这样就解决了标识的问题。

问题 2:传输层提供的服务- TCP 需要穿过层间的信息

第二个,应用进程要借助于传输层的提供的服务,通过层间的接口来传递数据。

层间接口必须要携带哪些信息?

  • 要传输的报文 相当于现实生活中的货物?,报文对于本层来说就是服务数据单元 SDU

  • 谁传给你的。也是我这边的应用进程在哪个 IP 守护在哪个 TCP(UDP) 的什么端口上。

    • 应用进程的标示:IP+TCP(UDP) 端口
    • 为什么要携带谁传的这个信息呢?因为对方可能传回来信息,就像现实生活中店小二把这个货物给你,你万一要退货呢?
  • 传给谁的。也是传送给对方的应用进程在哪个 IP 守护在哪个 TCP(UDP) 的什么端口上。

    • 应用进程的标示:对方的 IP+TCP(UDP) 端口号

有了这些信息之后,传输层实体(TCP 或者 UDP 实体),根据这些信息进行 TCP 报文段

(UDP数据报)的封装。这些信息包括源端口号,目标端口号,数据等等。

每次传输报文,都要携带这些信息吗?

如果 Socket API每次传输报文,都携带如此多的信息,这样太繁琐易错了,并且不便于管理。

所以说,有没有办法减少层间传输的信息量呢?

我们先来分析需要传输的信息,报文(可以看作货物?)每次都不一样,必须传输;剩下两个信息(谁传的、传给谁),每次都一样,有没有办法把他们合并在一起,从而减少信息量,提高管理的效率呢?

有的,这种方法就是 socket。socket 是什么呢? 我们可以把他理解为一个整数。

? 大家都学过 C 语言编程,我们打开一个文件操作系统的时候,会返回给我们一个整数,它叫做句柄。然后,我们对这个文件的操作,就会体现在文件句柄这个整数上。

是的,网络也是一样。下面我们会分别来看 TCP、UDP 是怎么做的。

TCP socket

两个应用进程使用 TCP 进行通讯时,会先建立连接。建立连接之后,TCP 会返回一个整数来代表我是谁、对方是谁。( 4 元组:源 IP、源 port、目标 IP、目标 port)

使用这个 4 元组与远程的应用进程通信,我们就不用在每一次发送报文的时候都指定我是谁、对方是谁。就像使用操作系统打开一个文件一样,操作返回一个文件句柄。以后使用这个文件句柄来标记文件,而不是使用这个文件的目录名、文件名。

这样的话,对操作系统来说简单容易管理,并且穿过层间的信息也比较少。

?

在上图的 tcp socket 当中操作 socket 的值,就是操作这个会话关系。

用这个整数值来标记通讯信息,只有你本地的操作系统知道。你的网络层以下不知道,对方也不知道。只有你的应用层、传输层知道,这是应用层和传输层直接的一个约定。

左侧的 TCP socket 创建了一个整数,代表了进程和进程之间的会话关系,右侧也创建了一个 socket 的值,这两个 socket 可以是完全不一样,因为 socket 是在操作系统内部分配的一个整数值。

建立连接的时候,操作系统返回一个整数,代表了我的IP,我的端口,对方的IP,对方的 TCP 端口。并且维护了一张表, socket 值对应我的 IP、我的端口、对方的 IP、对方的端口还有连接的状态。socket一旦建立起来,这个表项就建立起来了。

发送数据的时候,操作系统就可以查 socket 表,用什么 IP 来发,用什么样端口来发,发给对方的目标IP,对方端口是什么。对方的操作系统收到数据之后,会查找到对应的应用,从而把数据发给正确应用。

所以说, tcp socket 就是一个本地的标识。它代表了左侧的 IP、 TCP 端口上面的应用进程和右侧的 IP、 TCP 端口上的这个应用进程之间的通讯关系。

来看应用进程通信的另一个例子,三个应用进程在通信。

  • 第一个 endpoint 代表 IP 1.1.1.1,端口 233。
  • 第二个 endpoint 代表 IP 2.2.2.2,端口 80。

在这个第一个进程当中,操作系统用 socket 值 11111 代表了左 1 进程和左 2 进程的会话关系。而在第二个进程中,用 22222 表示会话关系。

同样的两个进程在通信,但是在不同的 endpoint 上,它具备不同的 socket 值所以说 TCP 的 socket 值代表是会话关系,而不仅仅是主机是谁的标识。

问题2:传输层提供的服务- UDP 层间信息代码

我们讲完 TCP 的 socket 之后,我们再看一下 UDP 。

我们知道对于 UDP 服务来说,两个进程之间的通信需要之前无需建立连接。而且每个报文传输都是独立的,前后发送的报文,可能要交给不同的应用进程。

比如说,我是一个守候在 UDP 上的进程,我向外发送报文,第一次要发送到进程 A,而第二次要发送到进程 B。

因此,我们只能用一个整数来代表本应用实体,而不代表一个会话关系。也就是说,这个整数只代表本地 IP 和本地 UDP 端口。这样,也能让穿过层间接口的信息最小。方便操作系统管理。

UDP socket

对于使用无连接服务(UDP)的应用而言,套接字是2元组的一个具有本地意义的标示:IP、port。用这个套接字,指定应用所在的一个端节点。

在发送数据报时,采用创建好的本地 socket,就不必在发送每个报文中指明自己所采用的 ip 和 port。但是在发送报文时,必须要指定目的地的 ip 和 udp port。

那么我在发送报文的时候需要携带哪些信息呢?

  • 第一,数据本身。
  • 第二,UTP socket 值。代表我的 IP 和我的端口。
  • 第三,对方的 IP 地址和对方的 UDP 端口。

所以,TCP 每次传输只用交两个东西,而 UDP 需要交三个东西。

套接字(Socket)

套接字就像一个门一样,通过这个门把报文推出去,对方的应用进程就能通过这个门把报文收到。(那具体怎么做到的呢,后面传输层的章节,会有具体详细的介绍。)

当然传输层提供的服务,还包括网络层及以下的服务,还包括我的源主机,对方的目标主机,中间的网络交换设备,路由器交换机等等基础服务。我们借助这些服务建立 socket,通过这个 socket 进行发送和接收。

我们在编写软件时,只需要关心应用层的业务逻辑,就可以实现各种各样的应用。

问题 3:如何使用传输层提供的服务实现应用

如何来定义我们自己的协议,如何来编制应用程序,实现业务逻辑和动作次序,最后实现各种各样的应用。

应用层协议

应用层协议也是协议的一种,只不过在应用层。

它定义了分布式的应用进程,在创建过程当中,应该遵守的规则集合。也就是运行在不同端系统上的应用进程如何相互交换报文。

  • 交换的报文类型:请求和应答报文
  • 各种报文类型的语法:报文中的各个字段及其描述
  • 字段的语义:即字段取值的含义
  • 动作和次序:进程何时、如何发送报文及对报文进行响应的规则

那么应用协议是应用的全部吗?不对,应用协议仅仅是应用的一个组成部分。比如一个 web 应用,除了协议还包括 web 客户端、Web 服务器、HTML 等等。实际上协议只是规范了,我跟你在通信的过程当中应该遵守的规则而已。所以说,应用协议仅仅是应用的一部分。

协议分为两种:公开协议、专用(私有)协议。

  • 公开协议:协议是开放的,以 RFC 文档的形式发布。任何一个厂商和个人都可以遵守他的规范,来实现自己的应用。实现同一个协议的应用直接,就可以互操作了。比如 HTTP 就是公开协议。
  • 专用(私有)协议:协议是不公开的。如: Skype,通过互联网打电话的协议,他就是不公开的。

应用需要传输层提供什么样的服务?

应用层需要传承提供的服务是什么样子呢?有哪些指标可以衡量呢?

  • 数据丢失率

    • 有些应用对可靠性要求比较高,比如传输文件。因此它只能跑在 TCP 上。
    • 有些应用对可靠性要求不高,比如音频能容忍一定比例以下的数据丢失。因此它可以跑在 UDP 上。
  • 延迟:我把数据交过去到对方能够收到,中间有个延迟差。

    • 一些应用出于有效性考虑,数据传输有严格的时间限制,比如说 Internet 电话、交互式游戏。
  • 吞吐:单位时间内,我能发出去多少数据,有效地被对方接收。

    • 单位时间内,数据量比较少的时候,我发多少,对方就可以收多少。但是如果不断的增加我往外吐出去的数据量,对方可能就跟不上了。为什么呢?因为整个网络的这个吞吐量是有限的。还记得我们在第一章介绍的瓶颈链路吗?它决定了我们的最大带宽。
    • 一些应用(如多媒体)必须 需要最小限度的吞吐,从而使得应用能够有效运转。
    • 一些应用能充分利用可供使用的吞吐(弹性应用)
  • 安全性:机密性、完整性、可认证性(鉴别)

Internet 传输层提供的服务

我们再从一般的计算机网络,然后转移到特定的互联网。互联网的传输层包括了 TCP 和 UDP 这两种类型的协议。

TCP

  • TCP 向上提供的是可靠的传输服务
  • 流量控制:保证发送方不会淹没接受方
  • 拥塞控制:当网络出现拥塞时,能抑制发送方
  • 不能提供的服务:时间保证、最小吞吐保证和安全
  • 面向连接:要求在客户端进程和服务器进程之间建立连接

UDP 服务

  • 不可靠数据传输
  • 不提供的服务:可靠、流量控制、拥塞控制、 时间、带宽保证、建立连接

UDP 这么鸡肋?为什么要有 UDP 呢?

UDP存在的必要性

  • 能够区分不同的进程,而 IP 服务不能

    • 在 IP 提供的主机到主机端到端功能的基础上,区分了主机的应用进程
  • 无需建立连接,省去了建立连接时间,适合事务性的应用

  • 不做可靠性的工作,例如检错重发,适合那些对实时性要求比较高而对正确性要求不高的应用

    • 因为为了实现可靠性(准确性、保序等),必须付出时间代价(检错重发)
  • 没有拥塞控制和流量控制,应用能够按照设定的速度发送数据

    • 而在TCP上面的应用,应用发送数据的速度和主机向网络发送的实际速度是不一致的,因为有流量控制和拥塞控制

安全

TCP & UDP 都不提供安全的保证。都没有加密,都是明文通过互联网传输。

那我们想增加他的安全性,要怎么办呢?

在 TCP 之上加上 SSL 安全套接字层,它跑在 TCP 之上的。SSL 能够加强 TCP 的安全性,向应用进程 APP 提供安全的通信服务。

包括服务器端的认证、客户端的认证、私密传输、报文的完整性, SSL 都可以提供。

SSL在哪个层次呢?应用层(有些人说 SSL 在传输层,这种说法也可以,毕竟 SSL 是向应用层提供服务的。)

SSL 也提供 socket API。应用通过API将明文交给 socket,SSL将其加密在互联网上传输。详细情况,我们会在第8章进行说明。

? 我们经常访问的 HTTPS,就是跑在 SSL over TCP 之上的,这样才能保证浏览器和服务器之间的通信是安全的。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享