【网络】-- UDP协议

news/2024/5/18 13:00:09 标签: 网络, 服务器, udp

目录

传输层

再谈端口号

端口号范围划分

认识知名端口号(Well-Know Port Number)

两个问题

netstat

pidof

UDP协议 

UDP的特点

UDP的缓冲区

UDP使用注意事项

基于UDP的应用层协议 


传输层

        负责数据能够从发送端传输接收端。

再谈端口号

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

        说白了就是进行通讯的不同的进程。所以当底层收到数据时,其如果只知道目标地址,其根据IP地址就能找到对应的主机。但是接下来需要知道的就是,这个数据报应该向上递交给哪一个进程,即根据对应的Port端口号。

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

端口号范围划分

         0 - 1023:知名端口号,HTTP(80),HTTPS(443),SSH(22),FTP(21 / 23)等这些广为使用的应用层协议,他们的端口号都是固定的 (比如生活中:110一定时报警、120一定是急救)
        1024 - 65535:操作系统动态分配的端口号,客户端程序的端口号,就是由操作系统从这个范围分配的,用户可以自行绑定的端口。

认识知名端口号(Well-Know Port Number)

        有些服务器是非常常用的, 为了使用方便, 人们约定一些常用的服务器 都是用以下这些固定的端口号:
        执行 cat /etc/services 命令,可以看到知名端口号
Note: 我们自己写一个程序使用端口号时,要避开这些知名端口号。

        远程利用windows使用Xshell软件,连接远在外省的机器,因为我们使用的Xshell时客户端,而远端的服务器周而复始的,以启动一个绑定端口是22号的服务:

        进一步查看该服务:

        这个服务以d结尾,表示是守护进程(一般都是,不是强制规定),也可以看见其的SID与PID是相等的。

  • 守护进程:这个进程不退出,一直在后端提供服务。

         所以,当我们用Xshell连接之后,我们就能直接登上了,当我们启动的时候,一登陆成功,这个sshd就会在终端当中,为我们形成加载bash进程,然后给我们打出命令符。让我们进行输指令。

        然后将我们的指令字符串不断以网络发送的形式发送给服务器,然后让服务端执行,然后执行完再将结果给我们。

两个问题

#问: 一个进程是否可以bind多个端口号?

         可以的!

#问: 一个端口号是否可以被多个进程bind?

        不能! 

融汇贯通的理解:
         一个端口号被建立好并和进程绑定,而当有一个报文到了的时候,其是如何将对应的数据交给对应的进程的?


        常识:一个进程在进行服务的时候,除了listen套接字之外,每一次获取新连接(都会得到一个新的sockfd),对应的sockfd就是一个文件描述符。

        换句话说:其实在我们看来一个连接可以说就是一个文件,所以所谓的收到数据的本质就是:将数据放到对应的文件的接收缓冲区里,然后当前进程通过文件描述符进行文件的读取(因为进程与文件是通过文件描述表建立的关系)。无论未来进程想读取数据还是从底层网络里将数据拿上来,我们只要找到了进程,我们就能找到给进程所相关的文件缓冲区。

        所以:对于如何将底层TCP、UDP收到的数据交给特定的网络连接,其实就是转换成了:如何通过底层收到的端口号(携带端口号的相关报文),交付给特定进程。

        其做法:在内核当中其是采取哈希映射的关系,可以理解为key值为端口号,value值为进程的PCB的地址,所以当底层一旦收到数据时,系统当中直接查哈希表,直接找到对应的进程,然后就可以通过我们(我们在网络操作中,调用系统调用读数据的时候传的就是文件描述符)文件描述符,直接放在特定的文件当中,然后进程在上层用户调用read的时候就可以读取到了。

netstat

netstat 是一个用来查看网络状态的重要工具。
语法:netstat [选项]
功能:查看网络状态
常用选项
(显示不全,就需要进行提升)
  • n 拒绝显示别名,能显示数字的全部转化成数字。

  • l 仅列出有在 Listen (监听) 的服务状态。

  • p 显示建立相关链接的程序名。

  • t (tcp)仅显示tcp相关选项。
  • u (udp)仅显示udp相关选项。
  • a (all)显示所有选项,默认不显示LISTEN相关。

pidof

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


        其中UDP就属于传输层,并且端口号也是在传输层起作用。 

UDP协议 

#问:几乎任何协议都要首先解决的两个问题:a、如何分离(封装)? b、如何交付?

  1. 16位源端口号:表示数据从哪里来。
  2. 16位目的端口号:表示数据要到哪里去。
  3. 16位UDP长度:表示整个数据报(UDP首部+UDP数据)的长度。
  4. 16位UDP检验和:如果UDP报文的检验和出错,就会直接将报文丢弃。
  • a、如何分离(封装)?

        采用固定报头长度的策略(8个字节)。因为udp是不可靠协议,只要能够保证把数据能够交到对方主机(当然不保证也可以,反正只要发出去)就可以了,所以是固定长度。

        可以保证:将报头和有效载荷的分离。

  • b、如何交付? 

        根据报头中的16位端口号,进行向上交付。因为进程bind了端口号!之所以可以,就是因为这是一个约定,是一个客户端与服务端都知道,并且必须遵守的约定,这就叫做 "协议"

总结:

  • 所以对于应用层的代码编写的时候,都是用uint16_t类型来接收端口号。
  • udp通过固定长度的报头中提取到16位的UDP长度,以此知道如何正确的提取整个完整的报文数据。

即:根据上述可知,UDP是具有将报文一个一个正确接收的能力的!则,UDP是面向数据报的。

#问:如何理解udp报文的本身?

         底层中,这里所谓的报头实际上叫做:struct udp_hdr。传说中的udp报头,以及未来的所有报头,其实就是一个结构体类型(位断)。

struct udp_hdr
{
    uint32_t src_port:16;
    uint32_t dst_port:16;
    uint32_t udp_len:16;
    uint32_t udp_check:16;
}

UDP的特点

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

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

不可靠:

        指的是中性的特点,没有贬义的意思。在长距离传输的时候,如果要保证可靠性,一定意味着要做更多的工作,就意味着匹配的协议在实践上更复杂,其由于更加的复杂度,所以,其在使用成本以及维护成本上都是更高的。

        所以不可靠并不是十分的不好,一定原则上来说,反而更简单。

  • 面向数据报: 不能够灵活的控制读写数据的次数和数量。

面向数据报:

        应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并

用UDP传输100个字节的数据:

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

        怎么发就必须怎么收,发的报文必须是一个完整的报文。

#问:sendto / recvfrom / write / read / recv / send ……io类接口?

        在以往看来:这些函数是在网络中进行数据的收发(根本不是!)

        这些函数,其实本质是:拷贝函数!

        应用层用的都是系统调用接口,而目前我们所用的所有协议(通讯原则),全部用的是UDP / TCP提供的接口,所以内核层中的缓冲区一般用的都是传输层协议提供的。

        也就是说:对应传输层 -> 传输,即:缓冲区数据什么时候发,发多少,出错了怎么办,由其关心并处理。所以我们在应用层所写的代码,本质上:还是系统编程。我们将数据交给了参数层的缓冲区,并没有发送出去。

UDP的缓冲区

        UDP没有真正意义上的发送缓冲区。因为调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作。所以其对于发送缓冲区并没有特别强的需求,反正有数据就往下交。

        但是,UDP需要具有一定的接收缓冲区因为UDP上面就是应用层,应用层就是用户,如果程序员来不及调用recvfrom(因为,同时可能会到来很多UDP报文),来不及接收就有可能导致有些报文直接就被丢弃了,UDP不可靠,但是也要为丢包所带来的成本负责。(一个报文从一台主机传输到另一台主机,在传输过程中会消耗主机资源和网络资源。如果UDP收到一个报文后仅仅因为上次收到的报文没有被上层读取,而被迫丢弃一个可能并没有错误的报文,这就是在浪费主机资源和网络资源)

        这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致。如果缓冲区满了,再到达的UDP数据就会被丢弃。

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

全双工 VS 半双工:

        全双工 :一个文件描述符,如果既能读,同时又能写(可以理解为两个线程,同时一个线程读,一个线程写)。保证:只要接收缓冲区和发送缓冲区不冲突即可,不要用同一个缓冲区。

        半双工:一个文件描述符,再任意时刻,要么只能读,要么只能写,不能二者同时并行(可以理解为两个人正常聊天,只能其中一个人在说话)。

UDP使用注意事项

        我们注意到,UDP协议首部中有一个16位的最大长度,也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部)。

        然而64K在当今的互联网环境下,是一个非常小的数字。

        如果我们需要传输的数据超过64K,就需要在应用层手动的分包,多次发送,并在接收端手动拼装。

基于UDP的应用层协议 

  • NFS:网络文件系统。
  • TFTP:简单文件传输协议。
  • DHCP:动态主机配置协议(比如:笔记本连接网络前,上不了网,本质:没有IP地址。当连上网后,笔记本会自动获取一个IP地址,是路由器给的IP地址,就是路由器中部署了一种服务:DHCP)。
  • BOOTP:启动协议(用于无盘设备启动)。
  • DNS:域名解析协议。

同时,也包括我们字节所写得UDP程序时,自定义的应用层协议。


http://www.niftyadmin.cn/n/262659.html

相关文章

阿里6面,成功唬住面试官拿了26K,突然感觉软件测试面试貌似不太难...

一次闲聊,一个在阿里上班的朋友突然说起他在阿里的面试经历。 朋友说,阿里的面试挺独特,每轮面试都没有 HR 约时间,一般是晚上 8 点左右面试官来一个电话,问是否能面试,能的话开始面,不能就约一…

linux-01-基础回顾-虚拟机安装linux(centos7)、linux常用命令

文章目录 Linux-Day01课程内容1. 前言1.1 什么是Linux1.2 为什么要学Linux1.3 学完Linux能干什么 2. Linux简介2.1 主流操作系统2.2 Linux发展历史2.3 Linux系统版本 3. Linux安装3.1 安装方式介绍3.2 安装VMware3.3 安装Linux3.4 网卡设置3.5 安装SSH连接工具3.5.1 SSH连接工具…

没有U盘电脑如何使用本地硬盘安装Ubuntu20.04(双系统)

环境: DELL7080台式机 Ubuntu20.04 两块硬盘 问题描述: 没有U盘电脑如何使用本地硬盘安装Ubuntu20.04(双系统) 解决方案: 一、下载镜像文件 1.上线自行下载安装镜像文件 二、分区 1.win10下磁盘管理压缩2个分区一个10G左右制作安装盘,一个几百G安装系统使用 10…

为什么软件测试外包公司更受软件企业欢迎?软件测试报告需要多少钱?

劳动派遣或劳务派遣的用工模式古已有之,是人力资源销售市场不可避免的态势。软件测试顺应时代开展检测业务外包这一行业细分领域,越来越多软件外包公司尤其是小微型企业慢慢意识到了软件测试业务外包通常能够持续减少企业的各种成本费,使企业…

湿法冶金以及铼提取工艺,湿法冶金工艺特点及工艺流程

湿法冶金是利用浸出剂在一定温度压力下与矿石接触,把矿石中有用的金属溶解后再从溶液中回收有价金属的一种工艺,因为其过程大都是在水溶液中进行,所以又被称为“水法冶金”。 01 湿法冶金工艺特点及工艺流程 湿法冶金作为解决我国金属矿产资…

数据库系统-查询优化

文章目录 一、查询优化概述二、优化的基本思路2.1 语义优化-内容等价性2.2 语义优化-语法等价性2.3 执行优化(物理层优化)2.4 优化在整个DBMS的位置 三、逻辑查询优化3.1 逻辑优化整体思路3.2 关系代数操作次序交换的等价性定理1 连接&连接 积&积 交换律定理2 连接&…

一个全端通用的折叠面板,个性定制支持复杂表格

使用uniapp框架全端通用的折叠面板,下载地址见文末 介绍 这是一个全端通用的折叠面板组件,可以折叠/展开的内容区域,支持复杂的表格形式展示,简单的设置即可实现,节省效率必备。 插件含全部源码,可以给您…

使用chatgpt分析 too many open files 问题-未验证

java.io.IOException: Too many open files 怎么能定位到时哪行代码出的问题 ? 2023/4/25 19:46:33 当出现类似 "java.io.IOException: Too many open files" 的错误时,通常是因为程序打开了过多的文件句柄(File Handles&#xff…