肝了一周的 UDP 基础知识终于出来了。

我把自己以往的文章汇总成为了 Github ,欢迎各位大佬 star
https://github.com/crisxuan/bestJavaer
已提交此篇文章

位于应用层和 络层之间,是 OSI 分层体系中的第四层,同时也是 络体系结构的重要部分。运输层主要负责 络上的端到端通信。

TCP 如何判断是哪个端口的呢p>

还记得数据包的结构吗,这里来回顾一下

但是为了统一,一般在计算机 络中我们统一称 TCP 和 UDP 的 文为 ,这个就相当于是约定,到底如何称呼不用过多纠结啦。

套接字

在 TCP 或者 UDP 发送具体的 文信息前,需要先经过一扇 ,这个门就是,套接字向上连接着应用层,向下连接着 络层。在操作系统中,操作系统分别为应用和硬件提供了。而在计算机 络中,套接字同样是一种接口,它也是有接口 API 的。

使用 TCP 或 UDP 通信时,会广泛用到套接字的 API,使用这套 API 设置 IP 地址、端口 ,实现数据的发送和接收。

  1. socket 中的 API 用于创建通信链路中的端点,创建完成后,会返回描述该套接字的。

就像使用文件描述符来访问文件一样,套接字描述符用来访问套接字。

  1. 当应用程序具有套接字描述符后,它可以将唯一的名称绑定在套接字上,服务器必须绑定一个名称才能在 络中访问
  2. 在为服务端分配了 socket 并且将名称使用 bind 绑定到套接字上后,将会调用 listen api。 表示客户端愿意等待连接的意愿,listen 必须在 accept api 之前调用。
  3. 客户端应用程序在流套接字(基于 TCP)上调用 发起与服务器的连接请求。
  4. 服务器应用程序使用API 接受客户端连接请求,服务器必须先成功调用 bind 和 listen 后,再调用 accept api。
  5. 在流套接字之间建立连接后,客户端和服务器就可以发起 read/write api 调用了。
  6. 当服务器或客户端要停止操作时,就会调用 API 释放套接字获取的所有系统资源。

虽然套接字 API 位于应用程序层和传输层之间的通信模型中,但是套接字 API 不属于通信模型。套接字 API 允许应用程序与传输层和 络层进行交互。

在往下继续聊之前,我们先播放一个小插曲,简单聊一聊 IP。

聊聊 IP

是的缩写,是 TCP/IP 体系中的协议。设计 IP 的初衷主要想解决两类问题

  • 提高 络扩展性:实现大规模 络互联
  • 对应用层和链路层进行解藕,让二者独立发展。

IP 是整个 TCP/IP 协议族的核心,也是构成互联 的基础。为了实现大规模 络的互通互联,IP 更加注重适应性、简洁性和可操作性,并在可靠性做了一定的牺牲。IP 不保证分组的交付时限和可靠性,所传送分组有可能出现丢失、重复、延迟或乱序等问题。

我们知道,TCP 协议的下一层就是 IP 协议层,既然 IP 不可靠,那么如何保证数据能够准确无误地到达呢p>

这就涉及到 TCP 传输机制的问题了,我们后面聊到 TCP 的时候再说。

端口

在聊端口 前,先来聊一聊文件描述以及 socket 和端口 的关系

为了方便资源的使用,提高机器的性能、利用率和稳定性等等原因,我们的计算机都有一层软件叫做操作系统,它用于帮我们管理计算机可以使用的资源,当我们的程序要使用一个资源的时候,可以向操作系统申请,再由操作系统为我们的程序分配和管理资源。通常当我们要访问一个内核设备或文件时,程序可以调用系统函数,系统就会为我们打开设备或文件,然后返回一个文件描述符fd(或称为ID,是一个整数),我们要访问该设备或文件,只能通过该文件描述符。可以认为该编 对应着打开的文件或设备。

而当我们的程序要使用 络时,要使用到对应的操作系统内核的操作和 卡设备,所以我们可以向操作系统申请,然后系统会为我们创建一个套接字 Socket,并返回这个 Socket 的ID,以后我们的程序要使用 络资源,只要向这个 Socket 的编 ID 操作即可。而我们的每一个 络通信的进程至少对应着一个 Socket。向 Socket 的 ID 中写数据,相当于向 络发送数据,向 Socket 中读数据,相当于接收数据。而且这些套接字都有唯一标识符——文件描述符 fd。

端口 是 位的非负整数,它的范围是 0 – 65535 之间,这个范围会分为三种不同的端口 段,由 Internet 码分配机构 IANA 进行分配

  • 周知/标准端口 ,它的范围是 0 – 1023
  • 注册端口 ,范围是 1024 – 49151
  • 私有端口 ,范围是 49152 – 6553

一台计算机上可以运行多个应用程序,当一个 文段到达主机后,应该传输给哪个应用程序呢么知道这个 文段就是传递给 HTTP 服务器而不是 SSH 服务器的呢p>

是凭借端口 吗文到达服务器时,是端口 来区分不同应用程序的,所以应该借助端口 来区分。

举个例子反驳一下 cxuan,假如到达服务器的两条数据都是由 80 端口发出的你该如何区分呢说到达服务器的两条数据端口一样,协议不同,该如何区分呢p>

所以仅凭端口 来确定某一条 文显然是不够的。

互联 上一般使用 源 IP 地址、目标 IP 地址、源端口 、目标端口 来进行区分。如果其中的某一项不同,就被认为是不同的 文段。这些也是 的基础。

确定端口

在实际通信之前,需要先确定一下端口 ,确定端口 的方法分为两种:

  • 标准既定的端口

标准既定的端口 是静态分配的,每个程序都会有自己的端口 ,每个端口 都有不同的用途。端口 是一个 16 比特的数,其大小在 0 – 65535 之间,0 – 1023 范围内的端口 都是动态分配的既定端口 ,例如 HTTP 使用 80 端口来标识,FTP 使用 21 端口来标识,SSH 使用 22 来标识。这类端口 有一个特殊的名字,叫做 。

  • 时序分配的端口

第二种分配端口 的方式是一种动态分配法,在这种方法下,客户端应用程序可以完全不用自己设置端口 ,凭借操作系统进行分配,操作系统可以为每个应用程序分配互不冲突的端口 。这种动态分配端口 的机制即使是同一个客户端发起的 TCP 连接,也能识别不同的连接。

多路复用和多路分解

我们上面聊到了在主机上的每个套接字都会分配一个端口 ,当 文段到达主机时,运输层会检查 文段中的目的端口 ,并将其定向到相应的套接字,然后 文段中的数据通过套接字进入其所连接的进程。下面我们来聊一下什么是多路复用和多路分解的概念。

多路复用和多路分解分为两种,即的多路复用(多路分解)和的多路复用(多路分解)

无连接的多路复用和多路分解

开发人员会编写代码确定端口 是周知端口 还是时序分配的端口 。假如主机 A 中的一个 10637 端口要向主机 B 中的 45438 端口发送数据,运输层采用的是 协议,数据在应用层产生后,会在运输层中加工处理,然后在 络层将数据封装得到 IP 数据 ,IP 数据包通过链路层尽力而为的交付给主机 B,然后主机 B 会检查 文段中的端口 判断是哪个套接字的,这一系列的过程如下所示

面向连接的多路复用与多路分解

如果说无连接的多路复用和多路分解指的是 UDP 的话,那么面向连接的多路复用与多路分解指的是 TCP 了,TCP 和 UDP 在 文结构上的差别是,UDP 是一个二元组而 TCP 是一个四元组,即源 IP 地址、目标 IP 地址、源端口 、目标端口 ,这个我们上面也提到了。当一个 TCP 文段从 络到达一台主机时,这个主机会根据这四个值拆解到对应的套接字上。

  • :这个字段占据 UDP 文头的前 16 位,通常包含发送数据 的应用程序所使用的 UDP 端口。接收端的应用程序利用这个字段的值作为发送响应的目的地址。这个字段是可选项,有时不会设置源端口 。没有源端口 就默认为 0 ,通常用于不需要返回消息的通信中。
  • : 表示接收端端口,字段长为 16 位
  • : 该字段占据 16 位,表示 UDP 数据 长度,包含 UDP 文头和 UDP 数据长度。因为 UDP 文头长度是 8 个字节,所以这个值最小为 8,最大长度为 65535 字节。
  • :UDP 使用校验和来保证数据安全性,UDP 的校验和也提供了差错检测功能,差错检测用于校验 文段从源到目标主机的过程中,数据的完整性是否发生了改变。发送方的 UDP 对 文段中的 16 比特字的和进行反码运算,求和时遇到的位溢出都会被忽略,比如下面这个例子,三个 16 比特的数字进行相加

? 然后再将上面的结果和第三个 16 比特的数进行相加

文章知识点与官方知识档案匹配,可进一步学习相关知识 络技能树首页概览22961 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年10月22日
下一篇 2020年10月22日

相关推荐