news 2026/1/31 4:04:46

6.5RTIPC之IDDP实例分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
6.5RTIPC之IDDP实例分析

6.5 RTIPC之IDDP实例分析

实时进程或实时线程之间,可以使用 RTIPC IDDP 协议通信。 IDDP 基于数据报(UDP风格),单次发送即完成传输。

IDDP 有如下特性:

  • 内存池管理:可通过setsockopt + IDDP_POOLSZ申请本地内存池,不使用 Xenomai 系统内存池。本地内存池的分配实际上在bind操作中完成,所以应在bind之前申请本地内存池。
  • 端口号:使用数字端口号管理,支持动态端口号分配
  • 端口标签化(Labeled Port):为端口赋予可读名称(如"iddp-demo"),通过名称连接。

Xenomai 源码demo/posix/cobalt目录自带了示例程序,非常完整的演示上述特性。

特性iddp-sendrecv.ciddp-label.c
寻址方式指定端口号通过标签动态查找端口
连接模式无连接(sendto/recvfrom类连接(connect+write/recvfrom
内存池单独申请独立内存池iddp-pool使用 Xenomai 系统内存池system heap(默认)

6.5.1 IDDP 无连接实时通信:iddp-sendrecv.c

1. 代码概述

iddp-sendrecv.c是一个使用 IDDP 协议的 C 语言示例程序,它展示了如何创建两个实时线程,并通过创建套接字、设置内存池、绑定端口以及使用sendtorecvfrom实现数据的发送与接收。该示例中,服务器线程绑定到一个实时时端口,接收来自客户端线程的数据报。客户端线程同样创建一个数据报套接字,绑定到一个不同的实时时端口,然后向服务器线程发送一系列预定义的消息。

  1. 头文件包含

代码开始部分包含了多个头文件,用于标准输入输出、线程操作、实时 IPC(进程间通信)、以及一些其他必要的系统功能。其中,<rtdm/ipc.h>是与 Xenomai 实时数据分发协议相关的头文件。

  1. 全局变量与常量
  • pthread_t svtid, cltid;:定义了两个线程变量,用于标识服务器线程和客户端线程。
  • IDDP_SVPORTIDDP_CLPORT:这两个宏定义了服务器线程和客户端线程所使用的实时时端口号。
#define IDDP_SVPORT 12 #define IDDP_CLPORT 13
  1. 消息数组

msg[]数组包含了服务器线程将要接收的一系列字符串消息。这些消息将用于演示服务器线程和客户端线程之间的通信。

static const char *msg[] = { "Surfing With The Alien", "Lords of Karma", "Banana Mango", "Psycho Monkey", "Luminous Flesh Giants", "Moroccan Sunset", "Satch Boogie", "Flying In A Blue Dream", "Ride", "Summer Song", "Speed Of Light", "Crystal Planet", "Raspberry Jam Delta-V", "Champagne?", "Clouds Race Across The Sky", "Engines Of Creation" };
2.main函数分析
  1. 信号屏蔽:程序开始时,屏蔽了一些信号(如SIGINTSIGTERMSIGHUP),以确保在这些信号到来时不会中断正在运行的线程。
  2. 线程属性设置:分别为服务器线程和客户端线程设置了线程属性,包括调度策略(SCHED_FIFO表示先进先出调度策略)、调度优先级等。
  3. 创建线程:通过pthread_create函数分别创建了服务器线程和客户端线程。
  4. 等待信号main函数会调用sigwait函数来等待任意一个被屏蔽的信号。当接收到信号后,程序会取消服务器线程和客户端线程,并通过pthread_join等待它们完成。
3.server(void *arg)服务器线程
  1. 创建套接字:使用socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_IDDP)创建一个类型为SOCK_DGRAM的数据报套接字。
  2. 设置内存池:通过setsockopt调用为服务器端点设置IDDP_POOLSZ,申请了一个本地32KB的内存池,这样数据报的内存分配可以从这个本地内存池中获取,避免从默认的 Xenomai 的系统内存池中分配。
poolsz = 32768; /* bytes */ ret = setsockopt(s, SOL_IDDP, IDDP_POOLSZ, &poolsz, sizeof(poolsz));
  1. 绑定套接字:使用bind函数将套接字绑定到指定的实时时端口IDDP_SVPORT
  2. 接收数据:通过一个无限循环,服务器线程不断调用recvfrom函数来接收数据报。当有新的数据报到达时,它会打印出接收到的数据报的字节数、内容以及发送端的端口号。
4.client(void *arg)客户端线程
  1. 创建套接字:同样地,客户端线程也使用socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_IDDP)创建了一个类型为SOCK_DGRAM的数据报套接字。
  2. 绑定套接字:客户端线程将其套接字绑定到一个不同的实时时端口IDDP_CLPORT。虽然这不是必须的,但是在某些情况下,绑定一个端口可以为发送端提供一个有效的对端名称。
  3. 发送数据:客户端线程在一个无限循环中调用sendto发送消息数组msg[]中的字符串,且每次发送时指定目标端口(IDDP_SVPORT=42)。每次发送后,它会切换到下一个消息,并使用clock_nanosleep函数休眠 500 毫秒,以便为系统其它服务提供一些运行时间。
5. 运行及输出

运行程序:

# ./iddp-sendrecv server: received 22 bytes, "Surfing With The Alien" from port 13 client: sent 22 bytes, "Surfing With The Alien" server: received 14 bytes, "Lords of Karma" from port 13 client: sent 14 bytes, "Lords of Karma" server: received 12 bytes, "Banana Mango" from port 13 client: sent 12 bytes, "Banana Mango" server: received 13 bytes, "Psycho Monkey" from port 13 client: sent 13 bytes, "Psycho Monkey" ......

观察内存池,其独立申请了iddp-pool@12内存池,没有使用system heap

cat /proc/xenomai/heap TOTAL FREE NAME 4194304 4183872 system heap 16384 16384 debug log 262144 261968 shared heap 262144 262112 private heap[427] 32768 32768 iddp-pool@12

6.5.2 IDDP 标签化实时通信:iddp-label.c

1. 代码概述

iddp-label.c是一个使用 IDDP 协议的 C 语言示例程序,它展示了如何通过标签化端口实现实时通信。它创建两个实时线程,并通过创建套接字、设置内存池、绑定端口以及使用connect/writerecvfrom在两个线程间交换数据。服务器线程绑定到动态端口,并设置标签,接收来自客户端线程的数据报。客户端线程同样创建一个数据报套接字,绑定到一个不同的实时时端口,连接服务器的标签化端口,并向服务器发送一系列预定义的消息。

  1. 头文件包含

代码开始部分包含了多个头文件,用于标准输入输出、线程操作、实时 IPC(进程间通信)、以及一些其他必要的系统功能。其中,<rtdm/ipc.h>是与 Xenomai 实时数据分发协议相关的头文件。

  1. 全局变量与常量
  • pthread_t svtid, cltid;:定义了两个线程变量,用于标识服务器线程和客户端线程。
  • IDDP_CLPORT:定义了客户端线程所使用的实时时端口号。
  • IDDP_PORT_LABEL:服务器端线程使用动态端口号,其端口标签为iddp-demo
#define IDDP_CLPORT 27 #define IDDP_PORT_LABEL "iddp-demo"
  1. 消息数组

msg[]数组包含了服务器线程将要接收的一系列字符串消息。这些消息将用于演示服务器线程和客户端线程之间的通信。

static const char *msg[] = { "Surfing With The Alien", "Lords of Karma", "Banana Mango", "Psycho Monkey", "Luminous Flesh Giants", "Moroccan Sunset", "Satch Boogie", "Flying In A Blue Dream", "Ride", "Summer Song", "Speed Of Light", "Crystal Planet", "Raspberry Jam Delta-V", "Champagne?", "Clouds Race Across The Sky", "Engines Of Creation" };
2.main函数分析
  1. 信号屏蔽:程序开始时,屏蔽了一些信号(如SIGINTSIGTERMSIGHUP),以确保在这些信号到来时不会中断正在运行的线程。
  2. 线程属性设置:分别为服务器线程和客户端线程设置了线程属性,包括调度策略(SCHED_FIFO表示先进先出调度策略)、调度优先级等。
  3. 创建线程:通过pthread_create函数分别创建了服务器线程和客户端线程。
  4. 等待信号main函数会调用sigwait函数来等待任意一个被屏蔽的信号。当接收到信号后,程序会取消服务器线程和客户端线程,并通过pthread_join等待它们完成。
3. 服务端(server线程)
  1. 创建实时套接字

    socket(AF_RTIPC,SOCK_DGRAM,IPCPROTO_IDDP);// 基于实时域(RTIPC)的IDDP协议
  2. 设置端口标签

    strcpy(plabel.label,IDDP_PORT_LABEL);setsockopt(s,SOL_IDDP,IDDP_LABEL,&plabel,sizeof(plabel));// 将标签绑定到套接字
  3. 动态绑定端口

    bind(s,(structsockaddr*)&saddr,sizeof(saddr));// saddr.sipc_port = -1表示自动分配
    • 绑定时内核自动分配空闲端口,并将标签注册到/proc/xenomai/registry/rtipc/iddp
  4. 循环接收消息

    recvfrom(s,buf,sizeof(buf),0,(structsockaddr*)&claddr,&addrlen);
4. 客户端(client线程)
  1. 绑定可选端口

    bind(s,(structsockaddr*)&clsaddr,sizeof(clsaddr));// clsaddr.sipc_port = IDDP_CLPORT(27)
    • 指定客户端的源端口,便于服务端识别(非必需,但示例中用于展示)。
  2. 标签连接

    setsockopt(s,SOL_IDDP,IDDP_LABEL,...);// 设置目标端口标签connect(s,(structsockaddr*)&svsaddr,sizeof(svsaddr));// svsaddr.sipc_port = -1表示搜索标签
    • 内核通过标签iddp-demo自动定位服务端端口,无需硬编码端口号。
  3. 实时消息发送

    write(s,msg[n],len);// 使用默认连接地址(已通过connect绑定)
    • 通过clock_nanosleep主动休眠,模拟实时任务的工作周期(500ms间隔)。
5. 运行及输出
# ./iddp-label server: received 22 bytes, "Surfing With The Alien" from port 27 client: sent 22 bytes, "Surfing With The Alien" server: received 14 bytes, "Lords of Karma" from port 27 client: sent 14 bytes, "Lords of Karma" server: received 12 bytes, "Banana Mango" from port 27 client: sent 12 bytes, "Banana Mango" ......
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/29 19:35:34

springboot基于Java Web的医院就诊系统医生排班预约挂号电子病历药品(源码+文档+运行视频+讲解视频)

文章目录 系列文章目录目的前言一、详细视频演示二、项目部分实现截图三、技术栈 后端框架springboot前端框架vue持久层框架MyBaitsPlus系统测试 四、代码参考 源码获取 目的 摘要&#xff1a;随着医疗信息化发展&#xff0c;传统就诊模式效率低、管理难。本文设计基于Spring…

作者头像 李华
网站建设 2026/1/29 22:27:09

抖音图片去水印工具:数字水印原理与无损去除技术的深度解析

在短视频与社交媒体内容共享盛行的背景下&#xff0c;用户对无水印高清图片的需求日益增长。然而&#xff0c;手动去除水印常面临效率低、画质损伤等问题。本文将介绍一款专业的抖音图片去水印网站&#xff0c;并从数字水印技术原理、去水印算法逻辑及用户体验优化三个维度展开…

作者头像 李华
网站建设 2026/1/30 9:52:11

【信息科学与工程学】【安全领域】安全基础——第十五篇 网安协同方案06-L5层面协同

L5会话层网络与安全协同方案深度架构一、会话层基础协同方案方案名称核心目标数据设计方法模型设计方法数学方程/算法依赖条件互斥条件数据协同方式协同效果指标1. 会话状态完整性保护​保护会话状态完整性和连续性会话状态模型&#xff1a;S {sid, seq, ack, window, flags, …

作者头像 李华
网站建设 2026/1/29 16:12:45

Rembg模型更新策略:持续保持最佳效果

Rembg模型更新策略&#xff1a;持续保持最佳效果 1. 智能万能抠图 - Rembg 在图像处理领域&#xff0c;自动去背景技术一直是内容创作、电商展示、UI设计等场景的核心需求。传统手动抠图效率低、成本高&#xff0c;而基于深度学习的智能抠图工具正逐步成为主流。其中&#xf…

作者头像 李华
网站建设 2026/1/29 15:13:50

ResNet18迁移学习实战:云端GPU 5分钟开跑

ResNet18迁移学习实战&#xff1a;云端GPU 5分钟开跑 引言 作为一名Kaggle选手&#xff0c;你是否遇到过这样的困境&#xff1a;本地电脑跑ResNet18模型训练慢如蜗牛&#xff0c;眼看截止日期只剩3天&#xff0c;第一轮epoch还没跑完&#xff1f;别担心&#xff0c;今天我要分…

作者头像 李华
网站建设 2026/1/30 11:50:22

测绘工程师必备:XY转经纬度实战案例解析

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个测绘工程专用的XY坐标转经纬度工具&#xff0c;功能包括&#xff1a;1. 支持多种工程坐标系&#xff08;如北京54、西安80等&#xff09;&#xff1b;2. 提供转换精度评估…

作者头像 李华