Linux| |对于UDP的学习

2023-05-16

UDP


# 前序

UDP(用户数据报协议)没有连接的,是面向数据报的,是不可靠

# 套接字

就是IP地址+端口号

IP地址:4字节

端口号:2字节,也就是说范围是0~65535

  • 端口号分为

  • 知名端口号

    • 0--1023:http,ssh,ftp,telnet等一些协议端口号都是固定的,对于操作系统来说是不能对其进行分配的

    • 一些固定的端口号

    1. ssh服务器,使用22端口

    2. ftp服务器,使用21端口

    3. telnet服务器,使用23端口

    4. http服务器,使用80端口

    5. https服务器,使用443端口

  • 操作系统动态分配的端口号

    • 客户端服务器的端口号,这个范围的端口号操作系统可以对其进行分配

  • 查看端口号

  • less /etc/services
     //就可以查看Linux下所有的端口号了

     

IP地址的理解:

  • IP地址用来标识一个主机

端口号的理解:

  • 端口号就是用来告诉操作系统要对于那一个进程进行操作,也就是说端口号就是用来标识一个进程

  • 一个端口号只可被一个进程所占用,但是一个进程可以拥有多个端口号,也就是进程和端口号是一对多的关系

  • 当我们写一个程序使用端口号的时候,要避开这些知名端口号

【问题】

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

    • 可以,因为一个进程可以打开多个文件描述符,而每一个文件描述符都对应着一个端口号,所以一个进程可以绑定多个端口号

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

    • 不可以

    • 如果一个进程先绑定一个端口号,然后再fork一个子进程,这样的话就实现了多个进程绑定一个端口号,但是不同的进程绑定同一个端口号是不可以

    • TIME_WAIT状态,服务器不能立即重启也说明不用进程不能同时绑定同一个端口号

  3. 多个进程可以监听同一个端口号吗?

    • 可以。监听之前要进行创建套接字->绑定ip::端口号->监听。我们可以在bind之前使用setsockopt函数,设置套接字选项,其中就包括REUSEADDR这个选项,表明多个进程可以复用bind函数中指定的地址和端口号

所以套接字就可以准确的标识一台主机上的一个进程,从而完成计算机之间的通信

计算机之间的通信:

  • 主机A的某个进程与主机B上的另一个进程进行通信

 

# 网络字节序转换

对于数据在网络中传输的时候有着自己遵循的传输规则大端传输

对于主机上的数据的传输序列有着两种:

  • 大端:即高位字节序放在低地址上

  • 小端:即低位字节序放在低地址上

  • 传输:均是先传输低地址上的数据然后是高地址上的数据

所以对于主机上的数据传输的时候传输到网络上的时候有可能导致数据错误(例如主机上是小端的时候,所以需要进行转换)

转换函数:

#include <arpa/inet.h>
​
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16 hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

h:表示主机host name

n:表示网络network

l:表示4字节long

s:表示2字节short

 

# 地址转换函数

  • 字符串转化为in_addr

    • in_addr_t inet_addr(const char* strptr)

  • in_addr转化为字符串

    • char* inet_ntoa(struct in_addr inaddr)

    • 具有不可重入性,也就是不可多次调用,因为该函数自己在静态区开辟一块空间用来存放IP地址字符串的

 

# UDP协议

UDP协议端格式

插图:UDP协议端格式

  • 16为UDP长度,表示整个数据报(UDP首部+UDP数据)的最大长度(64KB)

  • 检验和:如果校验和出错,就会直接丢弃(检验的是把首部和数据部分一起都检验)

    • 校验值首先在数据发送方通过特殊的算法计算得出,在传递到接收方之后,还要在重新计算。如果某个数据报在传输过程中被第三方篡改或者由于线路噪音等原因受到损坏,发送和接收方的校验计算值将不会相符,由此UDP协议可以检验是否出错。

  • 源端口号:在对方回信是选用,不需要时可用全0

  • 目的端口号:在终点交付报时必须要用到

  • 长度:UDP用户数据报的长度,其最小值是8(仅有首部)

UDP的特点

  • 无连接:直到对端的IP和端口号就直接进行传输,不需要建立连接

  • 不可靠:没有确认机制,没有重传机制;因为没有网络故障该段无法发送到对方,UDP协议层也不会给应用层返回任何错误信息

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

  • 控制选项较少,数据传输过程中延迟小,数据传输效率高

面向数据报

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

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

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

UDP的缓存区

  • UDP没有发送缓存区,调用sendto之后会直接交给内核,由内核·将数据传给网络层协议进行后续的传输动作。因为UDP是不面向连接的,所以没有重发机制,也就不需要发送缓存区将已经发送的数据保存下来为了发送失败进行重传做准备

  • UDP具有接收缓存区。但是这个接收缓存区不能保证收到的UDP报的顺序和发送UDP报的顺序一致;如果缓存区满了,在到达的UDP数据就会被丢弃

UDP的Socket既能读,也能写,全双工

UDP的使用注意事项

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

  • UDP首部中校验和的计算方法有些特殊。在计算校验和时,要在UDP用户数据报之前增加12个字节的伪首部

  • 伪首部既不向下传输也不想上递送,而仅仅是为了计算校验和

  • 与IP数据报的校验和只检验IP数据报的首部不同,UDP的校验和是把首部和数据部分一起都检验

伪首部:

插图:伪首部

基于UDP的应用层的协议

  • NFS:网络文件系统

  • TFTP:简单文件传输文件协议

  • DHCP:动态主机配置协议

  • DNS:域名解析协议

面试题用UDP实现可靠传输?

参考TCP的可靠性机制,在应用层实现类似的逻辑

  • 引用序列号,保证数据顺序

  • 引入确认应答,确保对端收到了数据

  • 引入超时重传,如果隔一段时间没有应答,就重发数据

 

1. 对于socket函数的使用

1.1 函数原型

int socket(int domain, int type, int protocol);
​
domain: 领域
    AF_INET:IPV4
    AF_INET6:IPV6
type: 类型
    SOCK_STREAM
    SOCK_DGARM
protocol: 协议

1.2 函数的作用

在通信领域中创建一个未被绑定的套接字,并且返回一个文件描述符,可以在以后对套接字进行操作的函数调用中使用

 

2. 对于bind函数的使用

2.1 函数原型

int bind(int socket, const struct sockaddr* address, socklen_t address_len);

2.2. 函数的作用

该函数采用先前创建好的套接字来对于IP地址以及端口号进行绑定,也就是表示该套接字可以标识出在一个网络中一台确定的主机并且主机中的进程

 

3. 对于recvfrom函数的使用

3.1 函数原型

ssize_t recvfrom(int socket, void* restrict buffer, size_t length, 
                 int flags, struct sockaddr* restrict address, 
                socklen_t* restrict address_len);
​
socket:要接受那一个套接字的消息
buffer:用来接收消息的缓存区
length:接收的消息的长度
flags:类型
address:空指针或者存储发送信息的sockaddr结构
addless_len:指定地址参数指向的sockaddr结构的长度
3.2 函数的作用

3.2 函数的作用  

用来接收从socket套接字发送来的消息。该套接字的sockaddr结构也知道

 

4. 对于sendto函数的使用

4.1 函数原型

ssize_t recvfrom(int socket, const void* message, size_t length, 
                 int flags, const struct sockaddr* dest_addr, 
                socklen_t* dest_len);

4.2 函数的作用

该函数是socket套接字从dest_addr出接收消息

 

5. 扩展知识

5.1 netstat

netstat是一个用来监控TCP/IP网络非重要工具

语法:netstat [选项]

功能:查看网络状态

选项:

  • -a,显示所有连线的Socket

  • -c,持续列出网络状态

  • -n,直接使用ip地址,而不通过域名服务器,也就是显示为数字

  • -l,显示监控中的服务器的Socket,仅列出监听(Listen)状态下的Socket

  • -p,显示正在使用Socket的程序的识别码和名称(PID/Program name)

  • -t,显示TCP传输协议的连线状况

  • -u,显示UDP传输协议的连线状况

  • -v,显示指令执行过程

  • -V,显示版本信息

  • -x,显示UNIX传输协议的连线状况

  • -s,显示网络工作信息统计表

  • -h,在线帮助

 

5.2 pidof

查看服务器进程id是非常方面

语法:pisdof [进程名]

功能:通过进程名,查看进程id

 

5.3 scp命令

基于ssh登录进行的网络安全的远程文件拷贝命令

例:要将自己当前路径下的clinet文件发送到主机IP为192.168.153.140的home目录下

scp ./clinet root@192.168.153.140:/home

 

 

5.4 关于防火墙的命令

  • 启动:systemctl start firewalld

  • 关闭:systemctl stop firewalld

  • 查看状态:systemctl status firewalld

  • 开机禁用:systemctl disable firewalld

  • 开机启用:systemctl enable firewalld

# 对于UDP书写服务器的思路

由于UDP是无连接的,所以对于两个处于同一局域网下计算机的进程之间通信,所以是不需要两台计算机之间的进程进行连接的,对于UDP使用的接口是需要包含知道从哪里接收消息的,要发送消息到哪里的。

  • 实现本地通信

    • 服务器

      • 只需要服务器创建一个套接字

      • 使该套接字对于本地地址(127.0.0.1)进行绑定,并且绑定一个端口号(1024--65535)就行了

        • 绑定本地地址是为了对于本地计算机的两个进程进程通信,而绑定端口号是为了绑定一个进程,是为了对于客户端进行发送消息到服务器的时候,可以找到服务器

      • 然后就接受客户端发来的消息

      • 对于客户端的消息进行处理然后就可以再次将处理后的消息进行返回

      • 插图:服务器流程

    • 客户端

      • 绑定一个套接字

        • 为了绑定一个进程,可以和服务器进行通信,将消息发送过去的时候要让服务器知道是哪一个进程再和他进程通信

      • 客户端只需要向服务器发送消息

      • 然后再次从客户端接收消息就好了,不需要考虑要进行连接

      • 插图:客户端流程

  • 实现处于同一局域网下的不同主机间进行通信

    • 服务器

      • 和本地通信的一致,只是对于套接字绑定的ip地址不一样了

      • 也对于套接字要绑定该局域网的ip地址以及一个端口号不需要在绑定本地地址(127.0.0.1)

        • 这样的话处于同一局域网下的计算机的进程就可以进行通信了

    • 客户端

      • 对于客户端来说没有任何改变,仍然是只需要知道服务器的ip和端口号就行了

 

# 对于UDP服务器要注意的问题

  • 启动客户端

    • 启动客户端的时候必须给客户端输入一个ip地址和端口号,这个ip地址和端口号也就是要知道客户端要发送消息给哪一个服务器进行发送

  • 启动服务器

    • 必须要给服务器绑定一个ip地址和端口号,也就是要注意该服务器处于该计算机上的哪一个进程上

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux| |对于UDP的学习 的相关文章

  • 如何在linux中以编程方式获取dir的大小?

    我想通过 C 程序获取 linux 中特定目录的确切大小 我尝试使用 statfs path struct statfs 但它没有给出确切的大小 我也尝试过 stat 但它返回任何目录的大小为 4096 请建议我如何获取 dir 的确切大小
  • C 语言的符号表

    我目前正在开发一种执行模式匹配的静态分析工具 我在用Flex https github com westes flex生成词法分析器 我编写了代码来管理符号表 我不太有经验C 所以我决定将符号表实现为线性链表 include
  • 使用循环在 C 中管道传输两个或多个 shell 命令

    我正在尝试执行ls wc l通过 C 语言程序 而不是使用命令行 这是我当前的工作代码 int main int pfds 2 pipe pfds pid t pid fork if pid 0 The child process clos
  • 使用 MAX_ORDER / 包含 mmzone.h

    根据https www kernel org doc Documentation networking packet mmap txt https www kernel org doc Documentation networking pa
  • 在 Mono 上运行 .Net MVC5 应用程序

    我正在 Windows 上的 Visual Studio 2013 中开发 Net 4 5 1 MVC5 应用程序 现在我想知道 是否可以在Linux Ubuntu 12 04 上运行这个应用程序 可以使用OWIN吗 Owin 可以自托管运
  • 从 Xlib 转换为 xcb

    我目前正在将我的一个应用程序从 Xlib 移植到 libxcb 但在查找有关我有时使用的 XInput2 扩展的信息时遇到了一些麻烦 libxcb 中有 XInput2 实现吗 如果是的话 在哪里可以找到文档 目前我在使用此功能时遇到问题
  • 内核的panic()函数是否完全冻结所有其他进程?

    我想确认内核的panic 功能和其他类似kernel halt and machine halt 一旦触发 保证机器完全冻结 那么 所有的内核和用户进程都被冻结了吗 是panic 可以被调度程序中断吗 中断处理程序仍然可以执行吗 用例 如果
  • Intel 上的 gcc 中的 _mm_pause 用法

    我参考过这个网页 https software intel com en us articles benefitting power and performance sleep loops https software intel com
  • C修改printf()输出到文件

    有没有办法修改printf为了将字符串输出到文件而不是控制台 我尝试在互联网上查找一些内容 发现了类似的电话dup dup2 and fflush这可能与此有关 EDIT 也许我不清楚 问题是这是C考试问题 问题如下 解释一个通常将字符串输
  • 错误:“rjags”的包或命名空间加载失败

    在终端的 conda 环境之一中 我能够成功安装包 rjags 但是 当我在该环境中运行 R 并运行库 rjags 时 出现以下错误 加载所需的包 coda 错误 rjags 的包或命名空间加载失败 rjags 的 loadNamespac
  • Apache 访问 Linux 中的 NTFS 链接文件夹

    在 Debian jessie 中使用 Apache2 PHP 当我想在 Apache 的文档文件夹 var www 中创建一个新的小节时 我只需创建一个指向我的 php 文件所在的外部文件夹的链接 然后只需更改该文件夹的所有者和权限文件夹
  • 使用os.execlp时,为什么`python`需要`python`作为argv[0]

    代码是这样的 os execlp python python child py other args this works os execlp python child py other args this doesn t work 我读过
  • cdc_acm:无法设置 dtr/rts - 无法与 USB cdc 设备通信

    我试图使用 pic24fj128gb206 枚举 usb cdc 设备 设备似乎已正确枚举 但是当我将设备连接到 Linux PC 时 我从内核收到以下警告消息 cdc acm 1 8 1 6 7 1 0 failed to set dtr
  • 如何在 Mac OSX Mavericks 中正确运行字符串工具?

    如何在 Mac OSX Mavericks 中正确运行字符串工具 我尝试按照我在网上找到的示例来运行它 strings a UserParser class 但我收到此错误 错误 Applications Xcode app Content
  • 研究缓冲区溢出时应该使用哪些版本的 GCC 或标志?

    最近 作为计算机工程专业的本科生 我一直在研究缓冲区溢出 出于兴趣 我开始研究缓冲区溢出 但在尝试在我的计算机上用 GCC 4 9 1 在 Debian Jessie 中 编译的我自己的 C 程序中实现它们时遇到了困难 我听说较新的编译器中
  • Linux下显卡内存使用情况

    Linux下有哪些工具可以监控显卡内存使用情况 NVIDIA 性能套件 http developer nvidia com content nvidia perfkit有Linux版本 可以实时监控各种显卡属性 包括显卡内存使用情况 显然
  • 来源和出口有什么区别?

    我正在编写一个 shell 脚本 以读取具有 key value 对的文件并将这些变量设置为环境变量 但我有疑问 如果我这样做source file txt是否会将该文件中定义的变量设置为环境变量 或者我应该逐行读取文件并使用导出命令设置它
  • 在 scp 的简单函数包装中使用波形符 ~ 时出现问题

    我想放置一个简单的bash功能在我的 bashrc围绕着scp通过接受 源 参数和 目标 参数来命令 到目前为止已经尝试过 function send eval scp 1 user annoyingly long server name
  • 如何在Linux中自动启动需要X的应用程序

    我试图在系统进入运行级别 5 时自动启动 X 应用程序 这样做的正确方法是什么 我写了一个脚本并将其放在 etc init d 中 我已运行适当的 chkconfig 命令来设置 etc rcX d 目录中的符号链接 一切工作正常 除了当我
  • 如何找到进程启动时使用的原始用户名?

    有一个 perl 脚本需要以 root 身份运行 但我们必须确保运行该脚本的用户最初没有以用户 foo 身份登录 因为它将在脚本运行期间被删除 那么 我如何查明自登录以来可能已多次起诉的用户是否在该链中的任何时间都没有模拟过 foo 我发现

随机推荐

  • 【PyQt】PyQt5开发环境搭建

    PyQt是基于python来开发Qt可视化窗口的简称 xff0c Qt本身是基于C 43 43 开发 xff0c 性能较好 xff0c Qt与Python结合后 xff0c 在Python的支持下可以快速地开发桌面应用程序 文章目录 1 P
  • 【C++】9.GIS应用:开源GIS平台开发入门(MapServer+QGIS+PostGIS+OpenLayers)

    GIS地理信息处理相关 文章目录 1 GIS软件工具2 MapServer服务器3 QGIS桌面软件QGIS加载csv数据 4 PostGIS数据库5 OpenLayers JS 浏览器客户端 1 GIS软件工具 在GIS数据处理时 xff
  • 【C++】6.网络编程:socket实现通信(文字、语音)

    常见的通信方式有文本 语音 xff0c 下面用C 43 43 实现 xff1a 参考 xff1a https blog csdn net Robot hfut article details 102862052 https blog csd
  • 【ros】6.ros激光雷达SLAM(建图定位)

    百行业为先 xff0c 万恶懒为首 梁启超 文章目录 smirk 1 激光SLAM blush 2 二维激光SLAM satisfied 3 三维激光SLAM x1f60f 1 激光SLAM SLAM xff08 同步定位与地图构建 xff
  • 【ros】7.ros导航navigation(定位规划)

    物竞天择 xff0c 优胜劣汰 xff1b 苟不自新 xff0c 何以获存 梁启超 文章目录 smirk 1 ros导航 blush 2 2d导航 satisfied 3 3d导航 x1f60f 1 ros导航 ros机器人有个导航功能 x
  • 【两周年】我的创作纪念日(水)

    机缘 两年前的今天 xff0c 处于离职状态 xff0c 准备去另一个城市工作 xff0c 同时开始学习编程知识 IT技能 xff0c CSDN让我发现了一群热爱学习和分享的小伙伴 xff0c 也萌发了在这里扎根的想法 收获 不知不觉已经两
  • AI模型部署概述

    心口如一 xff0c 犹不失为光明磊落丈夫之行也 梁启超 文章目录 smirk 1 AI模型部署方法 blush 2 AI模型部署框架ONNXNCNNOpenVINOTensorRTMediapipe如何选择 satisfied 3 AI模
  • 【C++】1.语言基础:八股文

    心口如一 xff0c 犹不失为光明磊落丈夫之行也 梁启超 文章目录 smirk 1 语言基础内存分配指针参数传递和引用参数传递四种强制转换面向对象的三大特性并举例 define 和别名 typedef 的区别 blush 2 标准库STL介
  • 【VSLAM】ORB-SLAM3安装部署与运行

    心口如一 xff0c 犹不失为光明磊落丈夫之行也 梁启超 文章目录 smirk 1 ORB SLAM3介绍 blush 2 代码安装部署1 安装ros与opencv2 安装Pangolin作为可视化和用户界面3 安装Eigen3一个开源线性
  • 【Linux运维】ACPI BIOS Error问题解决

    今天帮朋友装个ubuntu系统 xff0c 遇到一个问题记录一下 报错与现象 xff1a ACPI BIOS Error 电脑花屏 解决方法 xff1a 插入启动盘 xff0c 当进入引导界面后 xff0c 键盘输入 e xff0c 编辑L
  • catkin_make的时候发生了什么

    原链接http community bwbot org topic 182 运行测试平台 小强ROS机器人 这是一个比较复杂的问题 xff0c 但是有时候会有莫名其妙的编译错误 xff0c 在找错误的过程中会非常需要了解这个过程 首先说一下
  • 【ros】8.有限状态机

    心口如一 xff0c 犹不失为光明磊落丈夫之行也 梁启超 文章目录 smirk 1 有限状态机认识 blush 2 一个简单的示例 satisfied 3 自动驾驶如何用有限状态机 x1f60f 1 有限状态机认识 有限状态机 xff08
  • 【C++】8.编译:CMake工具入门

    x1f60f xffe3 xffe3 x1f60f 这篇文章主要介绍CMake工具的入门使用 学其所用 xff0c 用其所学 梁启超 欢迎来到我的博客 xff0c 一起学习知识 xff0c 共同进步 x1f95e 喜欢的朋友可以
  • lwip --- (十六)TCP建立流程

    这一节我们就看看如何在我们的LWIP上实现一个http服务器的过程 xff0c 结合连接建立过程来理解TCP状态转换图和TCP控制块中各个字段的意义 这里先讲解一些与TCP相关的最基础的函数 xff0c 至于是怎样将这些函数合理高效的组织起
  • TCP和串口间的互相通信(透传)

    TCP和串口间的互相通信 xff08 透传 xff09 Tcp作为服务端 xff0c 接收消息 xff0c 通过串口发送 span class token keyword private span span class token retu
  • CONTINUING||重启

    现在是20年的8月13日 这是一个让自己非常难忘的一天 此时的我已经实现了当时自己曾经许下的诺言 xff0c 实现了自己当时年少无知的梦想 找到了一个好公司 xff0c 有了一份好工作 xff08 tx xff09 但是这不是自己的梦想的终
  • c语言| |strstr函数的源代码以及自我实现

    strstr函数 strstr函数 xff1a strstr str1 str2 函数用于判断字符串str2是否是str1的子串 如果是 xff0c 则该函数返回str2在str1中首次出现的地址 xff1b 否则 xff0c 返回NULL
  • 如何在Linux下用vim编写代码

    1 首先进入到一个目录下 xff0c 输入命令 vim test c 2 便会在该目录下 xff0c 创建一个test c xff08 test c不存在 xff09 的文件 xff0c 如果test c存在的话 xff0c 那么就打开该文
  • C语言| |c语言下如何输出彩色的字

    c语言下如何输出彩色的字 使用格式 xff1a 样式开始 43 被修饰字符串 43 样式结束 样式开始 xff1a 033 43 参数1 43 xff1a 43 参数2 43 xff1a 43 参数3 43 m 参数1 xff1a 代表背景
  • Linux| |对于UDP的学习

    UDP 前序 UDP xff08 用户数据报协议 xff09 没有连接的 xff0c 是面向数据报的 xff0c 是不可靠 套接字 就是IP地址 43 端口号 IP地址 xff1a 4字节 端口号 xff1a 2字节 xff0c 也就是说范