传输层——UDP协议

目录

传输层

再谈端口号

端口号范围划分

认识知名端口号

两个问题

netstat

pidof

UDP协议

UDP协议端格式

UDP的特点

面向数据报

UDP的缓冲区 

UDP使用注意事项 

基于UDP的应用层协议 


传输层

在学习HTTP等应用层协议时,我们常常会简化理解,认为HTTP协议是直接在网络中发送请求和接收响应的。但实际上,这个过程远比这复杂。在应用层处理完数据后,这些数据会被传递给传输层。传输层会进一步处理这些数据,确保数据的可靠性和有效传输。数据会经过一系列的处理和优化。该过程贯穿整个网络协议栈,最终才能将数据发送到网络当中。

再谈端口号

端口号(Port)标识了一个主机上进行通信的不同的应用程序;

当主机从网络中接收到数据时,这些数据需要按照网络协议栈的自底向上的顺序进行交付。在这个过程中,数据应该被传递给哪个上层的应用程序,是由数据中包含的目的端口号来决定的。具体来说,在传输层处理这些数据时,会提取出其中的目的端口号信息。这个端口号是一个关键标识符,它告诉主机应该将接收到的数据传递给哪个特定的服务进程。

在TCP/IP协议中,用 "源IP","源端口号","目的IP","目的端口号","协议号" 这样一个五元组来标识一个通信(可以通过 netstat -n 查看); 

比如有多台客户端主机同时访问服务器,这些客户端主机上可能有一个客户端进程,也可能有多个客户端进程,它们都在访问同一台服务器。

服务器就是通过“源IP地址”、“源端口号”、“目的IP地址”、“目的端口号”以及“协议号”来识别一个通信的。

  • 首先,服务器会提取接收到的数据中的目的IP地址和目的端口号。这两个信息点共同确定了数据应该被发送至哪个特定的服务进程。
  • 接下来,服务器会检查数据中的协议号。这个号码指示了数据所使用的通信协议类型,告诉服务器应该如何处理这些数据。
  • 最后,服务器会注意到数据中的源IP地址和源端口号。这些信息在服务器准备发送响应时非常重要。服务器会将这两个值作为响应数据的目的IP地址和目的端口号,确保响应能够准确地返回给发送数据的客户端进程。

整个过程中,这些标识符共同工作,帮助服务器识别、管理和响应网络通信,从而维持了网络的顺畅运行。

通过netstat命令可以查看到这样的五元组信息。

  • 协议号:作为一个8位长的标识符,嵌入在IP报头中。它的主要作用是指示数据报中所携带数据所使用的通信协议类型。当数据报到达目的主机时,IP层会参考这个协议号,从而决定应该将数据交给传输层的哪个协议进行进一步处理。这样,协议号确保了数据能够按照正确的通信规则被接收和处理。
  • 端口号:长度为16位,存在于UDP和TCP报头之中。它的核心职责是唯一地标识出一台主机上运行的特定进程。通过端口号,系统能够准确地将网络数据路由到正确的应用程序或服务中,实现了网络通信的精确性和高效性。

在网络协议栈中,协议号主要作用于传输层和网络层之间,它确保了数据在不同网络层之间能够按照正确的协议进行传输。而端口号则更贴近应用层与传输层之间的交互,它确保了数据能够准确地找到目标应用程序或服务,并与之进行通信。这两者的协同工作,共同构成了网络通信的基石。

端口号范围划分

端口号的长度是16位,因此端口号的范围是0 ~ 65535: 

  • 0 - 1023:知名端口号,HTTP,FTP,SSH等这些广为使用的应用层协议,他们的端口号都是固定的。
  • 1024 - 65535:操作系统动态分配的端口号。客户端程序的端口号,就是由操作系统从这个范围分配的。

认识知名端口号

有些服务器是非常常用的, 为了使用方便, 人们约定一些常用的服务器, 都是用以下这些固定的端口号:

  • ssh服务器, 使用22端口
  • ftp服务器, 使用21端口
  • telnet服务器, 使用23端口
  • http服务器, 使用80端口
  • https服务器, 使用443

执行下面的命令, 可以看到知名端口号

cat /etc/services

我们通过查看 /etc/services 文件可以看到知名端口号

我们自己写一个程序使用端口号时,要避开这些知名端口号

两个问题

1. 一个进程是否可以bind多个端口号?

是的,一个进程可以绑定多个端口号。因为一个进程可以打开多个文件描述符,而每个文件描述符都对应一个端口号,所以一个进程可以绑定多个端口号。在Linux系统中,内核会给每一个socket分配一个唯一的文件描述符,进程通过该文件描述符来区分对应的套接字。

我们限制的是从端口号到进程的唯一性,而没有要求从进程到端口号也必须满足唯一性,因此一个进程是可以绑定多个端口号的。

2. 一个端口号是否可以被多个进程bind?

不可以,一个端口号只能被一个进程绑定。这是因为端口号的绑定通常发生在服务器端,而一个端口通常只对应一个服务。一个服务对应一个进程,因此不存在两个进程同时绑定同一个端口号的情况。如果绑定一个已经被绑定的端口号,就会出现绑定失败的问题。

netstat

netstat是一个用来查看网络状态的重要工具。
语法:netstat [选项]
功能:查看网络状态
常用选项:

  • n 拒绝显示别名,能显示数字的全部转化成数字
  • l 仅列出有在 Listen (监听) 的服務状态
  • p 显示建立相关链接的程序名
  • t (tcp)仅显示tcp相关选项
  • u (udp)仅显示udp相关选项
  • a (all)显示所有选项,默认不显示LISTEN相关 

查看TCP相关的网络信息时,一般选择使用nltp组合选项。

查看UCP相关的网络信息时,一般选择使用nlup组合选项。

查看LISTEN状态以外的连接信息,则去掉l选项,此时就会将处于其他状态的连接信息显示出来。 

pidof

在查看服务器的进程 id 时非常方便。
语法:pidof [进程名]
功能:通过进程名,查看进程id

UDP协议

UDP协议端格式

网络套接字编程所利用的各种接口,构成了应用层与传输层之间的桥梁,这些接口是操作系统提供的系统调用接口。开发者通过这些接口能够构建上层应用,如HTTP服务。当我们说HTTP是基于TCP的,这实际上意味着HTTP协议是在TCP套接字编程的基础上构建的。

进一步深入到传输层,这一层是由操作系统进行管理的。UDP作为传输层协议之一,是操作系统协议栈中内置的组件,其代码并非由上层用户编写。UDP的所有功能,包括数据的封装、解封装、校验和计算等,都是由操作系统负责实现的。因此,从某种角度看,网络功能也是操作系统不可或缺的一部分,它为上层应用提供了稳定、可靠的数据传输服务。

UDP协议格式如下: 

  • 16位源端口号:表示数据从哪里来。
  • 16位目的端口号:表示数据要到哪里去。
  • 16位UDP长度:表示整个数据报(UDP首部+UDP数据)的长度。
  • 16位UDP检验和:如果UDP报文的检验和出错,就会直接将报文丢弃。

UDP如何将报头与有效载荷进行分离?

UDP 的报头结构是固定的,包含四个字段,每个字段的长度都是16位,合计8字节。这种设计意味着UDP的报头长度是固定的,不随数据内容而变化。因此,当UDP接收报文时,一旦读取了前8个字节,接下来的数据就都被视为有效载荷,即实际要传输的应用层数据。

UDP如何决定将有效载荷交付给上层的哪一个协议?

UDP作为传输层协议,负责将数据从发送方传输到接收方。由于UDP上层涉及众多应用层协议,它必须能够区分这些数据应当交付给哪个上层协议或应用层进程。为了实现这一点,应用层的每个网络进程都与一个特定的端口号相关联。服务器端进程通常会显式地绑定到一个固定的端口号上,而客户端进程则通常会被系统动态分配一个端口号。

当UDP接收到一个报文时,它会查看报头中的目的端口号。这个端口号就像是一扇门,指示UDP应当将数据交付给哪个应用层进程。通过这种方式,UDP能够确保数据准确无误地传输到正确的目的地,即对应的应用层进程。

内核中用哈希的方式维护了端口号与进程ID之间的映射关系,因此传输层可以通过端口号得到对应的进程ID,进而找到对应的应用层进程。

如何理解报头?

操作系统是C语言写的,而UDP协议又是属于内核协议栈的,因此UDP协议也一定是用C语言编写的,UDP报头实际就是一个位段类型。

例如:

UDP数据封装:

  • 在应用层将数据传递给传输层后,传输层会为该数据创建一个UDP报头对象,并根据需要填充报头中的各个字段。
  • 接下来,操作系统会在内核中分配一块缓冲区,用于存放即将发送的UDP报文。这个缓冲区将包含之前生成的UDP报头以及从应用层传递下来的有效载荷数据。操作系统会将这两部分数据拷贝到缓冲区中,形成一个完整的UDP报文,准备进行后续的网络传输。

UDP数据分用:

  • 当传输层从网络层接收到一个报文时,它会首先读取该报文的前8个字节。通过解析这些字节,传输层能够提取出报文中的目的端口号。
  • 一旦获取了目的端口号,传输层会在本地系统中查找与该端口号相关联的应用层进程。

UDP的特点

UDP传输的过程类似于寄信.

  • 无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接;
  • 不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层返回任何错误信息;
  • 面向数据报: 不能够灵活的控制读写数据的次数和数量;

面向数据报

应用层交给UDP多长的报文, UDP原样发送, 既不会拆分, 也不会合并;
比如用UDP传输100个字节的数据:

  • 如果发送端调用一次sendto,发送100个字节,那么接收端也必须调用对应的一次recvfrom,接收100个字节; 而不能循环调用10次recvfrom,每次接收10个字节;

UDP的缓冲区 

  • UDP没有真正意义上的 发送缓冲区。调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作;
  • UDP具有接收缓冲区。但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致; 如果缓冲区满了,再到达的UDP数据就会被丢弃;

UDP的socket既能读,也能写,这个概念叫做 全双工 

UDP接收缓冲区的作用

UDP通常不会主动维护一个专门的接收缓冲区来存储接收到的报文。相反,它依赖于上层应用程序来及时读取和处理接收到的数据。如果上层应用程序未能及时读取UDP报文,那么这些数据可能会被操作系统丢弃,因为UDP是一个无连接的协议,不会为单个报文维护状态或重传机制。

当一个报文从一台主机传输到另一台主机时,确实会消耗主机和网络资源。如果因为上层应用程序未能及时读取数据而导致UDP丢弃报文,这确实是一种资源的浪费。然而,这并不是UDP协议本身的问题,而是上层应用程序处理数据不及时的结果。

为了避免这种情况,上层应用程序通常会实现自己的接收缓冲区来存储UDP报文,并确保及时读取和处理这些数据。这样,即使UDP本身不维护接收缓冲区,上层应用程序也能够控制数据的接收和处理,从而避免资源的浪费。

UDP使用注意事项 

我们注意到,UDP协议首部中有一个16位的最大长度。也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部).
然而64K在当今的互联网环境下,是一个非常小的数字。如果需要传输的数据超过64K,就需要在应用层进行手动分包,多次发送,并在接收端进行手动拼装。

基于UDP的应用层协议 

  • NFS: 网络文件系统
  • TFTP: 简单文件传输协议
  • DHCP: 动态主机配置协议
  • BOOTP: 启动协议(用于无盘设备启动)
  • DNS: 域名解析协议

当然,也包括你自己写UDP程序时自定义的应用层协议;

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值