【Linux】SocketCan c语言编程

2023-05-16

前言

为了能够对Socket CAN的深入理解,我们需要了解Socket的机制。

Socket的中文翻译为“插座”,在计算机世界里称为套接字。Socket最初是作为网络上不同主机之间进程的通信接口,后来应用越来越广,在同一主机上的不同进程之间通信也可以用Socket。简单来说,当网络上不同主机之间的两个进程(A、B)采用Socket进行通信时,那么它们之间需要建立一个通信端点,即创建Socket,创建Socket时就分配端口号和网络地址。当进程A向进程B发送数据时,那么进程A必须要知道进程B的网络地址及端口号

Socket采用C/S模型进行设计的,即Client/Server,面向客户端—服务器模型。
每一个Socket都用一个半相关描述: {协议,本地地址,本地端口}
一个完整的Socket则用一个相关描述: {协议,本地地址,本地端口,远程地址,远程端口}

一、Socket的类型

Socket有三种类型:

1、字节流套接字(SOCK_STREAM)

字节流的套接字可以提供可靠的数据传输、面向连接的通讯流。数据按何种顺序发送,就按何种顺序接收。例如,当我们按顺序发送A-B-C,那么在数据到达接收端时,它的顺序也是A-B-C。字节流套接字采用的是TCP(Transmission Control Protocol)协议。保证了数据传输的可靠性。
在这里插入图片描述
在这里插入图片描述

2、数据报套接字(SOCK_DGRAM)

数据报套接字定义了一种无连接的服务。所谓无连接服务,简单来说,即在发送数据时,无需在收发两端建立类似TCP那样的握手连接,在发送时,将数据打包,然后加上远程IP地址,即可把该数据包发送出去。数据通过相互独立的报文进行传输。并且是无序的、不可靠的传输。
在这里插入图片描述

在这里插入图片描述

3、原始套接字(SOCK_ROW)

原始套接字是我们需要关心的,因为我们的Socket CAN采用的即是原始套接字。该接口允许对较底层协议进行操作,如IP、ICMP等。原始套接字常用于检验新的协议实现或访问现有服务中配置的新设备。

套接字的工作流程如下:

先启动服务器,通过调用socket()函数建立一个套接字,然后调用bind()函数将该套接字和本地网络地址联系在一起,再调用listen()函数使套接字做好侦听的准备,并规定它的请求队列的长度,之后就调用accept()函数来接收连接。客户端在建立套接字之后就可调用 connect()和服务器建立连接。连接一旦建立,客户端和服务器之间就可以通过调用recv()/recvfrom()函数和send()/sendto函数来进行发收数据。最后,待数据传送结束后,双方调用close()函数关闭套接字。

下面我们来写两个简单的基于Socket的CAN应用程序,但是我们采用的是SOCK_ROW,因此在套接字工作流程上有区别于SOCK_STREAM和SOCK_DGRAM。由于Socket采用C/S模型进行设计的,所以我们的这两个程序也分别为Server和Client。

先是server端的程序,我们需要写一个服务器的程序,该程序接收来自客户端发来的数据,代码如下:

#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
int can_recv() {
    int sock_fd;
    unsigned long nbytes, len;
    struct sockaddr_can addr;
    struct ifreq ifr;
    /*为了能够接收CAN报文,我们需要定义一个CAN数据格式的结构体变量*/
    struct can_frame frame;
    struct can_frame *ptr_frame;

    /* 建立套接字,设置为原始套接字,原始CAN协议 */
    sock_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    /* 对CAN接口进行初始化,设置CAN接口名,即当我们用ifconfig命令时显示的名字 */
    strcpy(ifr.ifr_name, "can0");
    ioctl(sock_fd, SIOCGIFINDEX, &ifr);
    /*设置CAN协议 */
    addr.can_family = AF_CAN;
    addr.can_ifindex = 0;
    /*将刚生成的套接字与网络地址进行绑定*/
    bind(sock_fd, (struct sockaddr *)&addr, sizeof(addr));
    /*开始接收数据*/
    nbytes = recvfrom(sock_fd, &frame, sizeof(struct can_frame), 0,
                      (struct sockaddr *)&addr, (socklen_t *)&len);
    /*get interface name of the received CAN frame*/
    ifr.ifr_ifindex = addr.can_ifindex;
    ioctl(sock_fd, SIOCGIFNAME, &ifr);
    printf("Received a CAN frame from interface %s\n", ifr.ifr_name);
    /*将接收到的CAN数据打印出来,其中ID为标识符,DLC为CAN的字节数,DATA为1帧报文的字节数*/
    printf("CAN frame:\nID = %x\nDLC = %x\nDATA = %s\n", frame.can_id,
           frame.can_dlc, frame.data);

    ptr_frame = &frame;

    return 0;
}

接下来是CAN的发送程序,即客户端,代码如下:

#include <linux/can.h>
#include <linux/can/raw.h>
#include <net/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
int can_send() {
    int sock_fd;
    unsigned long nbytes;
    struct sockaddr_can addr;
    struct ifreq ifr;
    struct can_frame frame;
    /*建立套接字,设置为原始套接字,原始CAN协议 */
    sock_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    /* 对CAN接口进行初始化,设置CAN接口名,即当我们用ifconfig命令时显示的名字 */
    strcpy((char *)(ifr.ifr_name), "can0");
    ioctl(sock_fd, SIOCGIFINDEX, &ifr);
    printf("can0 can_ifindex = %x\n", ifr.ifr_ifindex);
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;
    /*将刚生成的套接字与CAN套接字地址进行绑定*/
    bind(sock_fd, (struct sockaddr *)&addr, sizeof(addr));
    /*设置CAN帧的ID号,可区分为标准帧和扩展帧的ID号*/
    frame.can_id = 0x1122;
    strcpy((char *)frame.data, "hello");
    frame.can_dlc = strlen((char *)frame.data);
    printf("Send a CAN frame from interface %s\n", ifr.ifr_name);
    /*开始发送数据*/
    nbytes = sendto(sock_fd, &frame, sizeof(struct can_frame), 0,
                    (struct sockaddr *)&addr, sizeof(addr));

    return 0;
}

上面两个程序看完后,大家可能会有疑问,为什么这两个程序没有listen()和accept()函数呢?其实这两个程序是独立的运行的,并不像字节流套接字(SOCK_STREAM)和数据报套接字(SOCK_DGRAM),需要先运行服务器进行侦听。SOCK_STREAM和SOCK_DGRAM的两个server和client程序是通过网络相互收发数据。而CAN的socket的server和client程序收发数据的对象是CAN总线。server从CAN总线上接收数据,client将数据发到CAN总线上,当CAN总线上有数据时,server才能接收数据,当CAN总线空闲时,client才能将数据发送出去。

以上是对套接字的简单理解,并附上socket CAN的简单上层应用代码,如有不足之处,敬请谅解!

(转载地址 https://blog.csdn.net/m0_61011506/article/details/121282163?spm=1001.2014.3001.5506)

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

【Linux】SocketCan c语言编程 的相关文章

  • 如何在 Linux 中使用单行命令获取 Java 版本

    我想通过单个命令获取 Linux 中的 Java 版本 我是 awk 的新手 所以我正在尝试类似的事情 java version awk print 3 但这不会返回版本 我将如何获取1 6 0 21从下面的Java版本输出 java ve
  • 远程linux服务器到远程linux服务器大型稀疏文件复制 - 如何?

    我有两台 CentOS 5 4 服务器 每台服务器上都安装了 VMware Server 假设我始终对 vmware 虚拟机使用稀疏文件 将虚拟机文件从一台服务器复制到另一台服务器的最可靠 最快速的方法是什么 虚拟机的文件复制起来很痛苦 因
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • sqlite 插入需要很长时间

    我正在将不到 200 000 行插入到 sqlite 数据库表中 我只是在终端中通过 sqlite3 使用一个非常简单的 sql 文件 我打赌它已经运行了至少 30 分钟 这是正常现象还是我应该关闭该过程并尝试不同的方法 sqlite中的插
  • Windows 与 Linux 文本文件读取

    问题是 我最近从 Windows 切换到 Ubuntu 我的一些用于分析数据文件的 python 脚本给了我错误 我不确定如何正确解决 我当前仪器的数据文件输出如下 Header 有关仪器等的各种信息 Data 状态 代码 温度 字段等 0
  • Gradle 1.3:build.gradle 不构建类

    这里有一个新问题 我有一个 build gradle 文件apply plugin java在其中 并与 java 项目 包关联 当我跑步时gradle build从命令行我得到 compileJava UP TO DATE process
  • R 未获取用户库

    我有一个带 R 3 6 0 的 Fedora 30 系统 用户库设置在Renviron就像这个 R LIBS USER R LIBS USER R x86 64 redhat linux gnu library 3 6 事实上 它出现在交互
  • 如何从类似于 eclipse 的命令行创建可运行的 jar 文件

    我知道 eclipse 会生成一个可运行的 jar 文件 其中提取并包含在该 jar 文件中的所有库 jar 文件 从命令提示符手动创建 jar 文件时如何执行类似的操作 我需要将所有 lib jar 解压到类文件夹中吗 目前我正在使用 j
  • Linux 上的 Python 3.6 tkinter 窗口图标错误

    我正在从 Python GUI 编程手册 学习 Python GUI 某项任务要求我通过将以下代码添加到我的配方中来更改窗口图标 Change the main windows icon win iconbitmap r C Python3
  • numpy 未定义符号:PyFPE_jbuf

    我正在尝试使用一百万首歌曲数据集 为此我必须安装 python 表 numpy cython hdf5 numexpr 等 昨天我设法安装了我需要的所有内容 在使用 hdf5 遇到一些麻烦之后 我下载了预编译的二进制包并将它们保存在我的 b
  • 怎样才能使 Windows 成为一个开箱即用的 POSIX 兼容操作系统?

    这个问题的动机是我的一个牵强的梦想 即 nix 平台上可用的许多优秀软件可以轻松移植到 Windows 微软最近对开源和开放性采取了不同的方法 所以我真的很想知道如果微软有这样的倾向 这样的事情会有多可行 我很好奇的一些更具体的事情是 是否
  • gethostbyname() 或 getnameinfo() 如何在后台工作?

    How gethostbyname or getnameinfo 在后台工作 include
  • 伊迪德信息

    重新定义问题 有什么方法可以获取所连接显示器的序列号吗 我想收集显示器的Eid信息 当我使用 logverbose 选项运行 X 时 我可以从 xorg 0 log 文件中获取它 但问题是 如果我切换显示器 拔出当前显示器 然后插入另一个显
  • 无法安装 WWW::Curl::Easy: SZBALINT/WWW-Curl-4.17.tar.gz : make NO

    我正在尝试在我的 Fedora 26 机器上安装 WWW Curl Easy gcc c I usr include D REENTRANT D GNU SOURCE O2 g pipe Wall Werror format securit
  • 为什么在 Linux 上字符串文字的内存地址与其他字符串文字的内存地址如此不同?

    我注意到字符串文字在内存中的地址与其他常量和变量 Linux 操作系统 非常不同 它们有许多前导零 未打印 Example const char h Hi int i 1 printf p n void h printf p n void
  • 无法执行'x86_64-conda_cos6-linux-gnu-gcc':没有这样的文件或目录(pysam安装)

    我正在尝试安装 pysam 执行后 python path to pysam master setup py build 这个错误的产生是 unable to execute x86 64 conda cos6 linux gnu gcc
  • 如何在Python中独立于语言安装(linux)获取用户桌面路径

    我找到了 如何找到用户桌面的路径 的几个问题和答案 但在我看来它们都已失效 至少我找到的那些 原因是 如果用户安装的 Linux 不是英语 他或她的桌面很可能位于除 Desktop 例如 对于瑞典语 我相信它是在 Skrivbord 谁知道
  • sleep 0 有特殊含义吗?

    我看到很多用法sleep 0在我的一个客户项目中 代码看起来像这样 while true sleep 0 end 阅读一些像这样的答案this https stackoverflow com questions 3727420 signif
  • 适用于 KDE 和 Gnome 的 Gui [重复]

    这个问题在这里已经有答案了 我想为一个现在是 CLI 的应用程序编写一个 gui 它需要在 KDE 和 Gnome DE 中 看起来不错 充分利用用户的外观设置 如果我选择 Qt 或 GTK 我能够做到这一点吗 它们与两个 DE 集成良好吗
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何

随机推荐

  • POJ 1635 Subway tree systems

    题目 xff1a Some major cities have subway systems in the form of a tree i e between any pair of stations there is one and o
  • Openwrt添加定制一个软件包

    我深知前路风雨 xff0c 但我依然微笑前行 Openwrt的Makefile流程异于一般常用的Makefile xff0c 阅读起来难度太大 但是我么可以先通过如何使用 修改Makefile开始 xff0c 从Makefile的某个局部开
  • 无人机通信(WiFI/3G/4GLTE)

    无人机通信 xff08 WiFI 3G 4GLTE xff09 DJI 大疆创新的无人机可实时操控执行各项任务 Phantom3 还内置了全新的 Lightbridge 高清图传系统 xff0c 使飞机所拍摄的实时图像可远距离传输到移动设备
  • realsense D430 python采集深度图像,并保存为txt及pcd点云,用于open3D后处理

    D430点云是x y z 将realsense D430保存的点云文件 pcd 需要对数据进行处理 废话不多说 直接上代码 span class token comment coding utf 8 span span class toke
  • 隐藏符号 __dso_handle 问题

    这几天要给项目做移植 xff0c 重写了下Makfile 项目原是使用autoconf配置的 xff0c 但在新环境下对autoconf的支持不好 Makefile编写基本按autoconf生成的Makefile来的 xff0c 编译选项等
  • 类模板成员函数

    模板类的头文件 span class token macro property span class token directive hash span span class token directive keyword ifndef s
  • C++ 在.h文件中包含头文件和在.cpp文件中包含头文件的原则

    1 第一个原则 xff1a 如果可以不包含头文件 xff0c 那就不要包含了 xff0c 这时候前置声明可以解决问题 如果使用的仅仅是一个类的指针 xff0c 没有使用这个类的具体对象 xff08 非指针 xff09 xff0c 也没有访问
  • NRF24L01数据通信C程序

    NRF24l01 产品性能 xff1a 1 xff09 2 4GHZ全球开放ISM频段免许可使用 2 xff09 最高工作速率2Mbps GFSK高效调制 3 xff09 125个频道满足多点通讯和跳频通讯需求 4 xff09 1 9 3
  • gazebo仿真之xacro文件

    span class token operator lt span span class token operator span xml version span class token operator 61 span span clas
  • c++ 释放内存 野指针

    在释放内存之时 xff0c 不仅仅是将该块内存进行释放 xff0c 还要将指向该块内存的指针置为NULL 如果不置为NULL xff0c 下次继续使用该指针时会出现问题 具体看示例 在下面的示例中 xff0c 如果没有处理野指针的那句话 x
  • 二维码识别 -- 基于ros平台下的仿真

    生活中的二维码 二维码是用某种特定的几何图形按一定规律在平面 xff08 二维方向上 xff09 分布的黑白相间的图形记录数据符号信息的 xff1b 在代码编制上巧妙地利用构成计算机内部逻辑基础的 0 1 比特流的概念 xff0c 使用若干
  • ROS中控制机械臂抓取目标例程

    在上一个博文中介绍了一个简单的目标识别的例子 xff0c 在这篇博客中 xff0c 例如是别的结果 xff0c 完成机械臂的抓取控制 xff0c 主要进行程序的分析和学习 包含的头文件 xff1a include lt ros ros h
  • STM32_Debug 使用ST-Link进行调试出现Error:Flash Download Failed-"Cortex-M3" 解决方案

    在Debug窗口依次注意以下几个点 xff1a 1 选择与主控芯片相配套的芯片 2 选择ST Link Debugger 此处注意该页面最下面一行可不更改 xff08 亲测有效 xff09 3 接上图点击进入Setting xff0c 依次
  • 标准外设库(STD库)、HAL库、LL库三者区别

    转自 xff1a https blog csdn net zcshoucsdn article details 54613202 2018 1 19 HAL库详解见STM32之HAL库详解 及 手动移植 STM32 Embedded Sof
  • FOC矢量控制

    FOC xff08 Filed Oriented Control xff09 是采用数学方法实现三相马达的力矩与励磁的解耦控制 主要是对电机的控制电流进行矢量分解 xff0c 变成励磁电流 I d Id 之后我将详细介绍一下这个算法的数学原
  • Linux网络编程8——对TCP与UDP的简易封装

    引言 每次使用socket通信 xff0c 都会有很对相似的操作 本文 xff0c 会对TCP与UDP通信做一简单封装 xff0c 并生成动态库 代码 my socket h ifndef MY SOCKET H define MY SOC
  • 分分钟带你入门无刷电机控制_P-NUCLEO-IHM001套件评测使用

    终于有时间将前段时间把有关ST公司的分分钟带你入门无刷电机控制 P NUCLEO IHM001套件评测的资料系统的整理一下 刚一开始接触接触这个套件的时候感觉这是什么鬼 xff0c 可以实现正弦波矢量控制 xff1f 这么强 xff0c 慢
  • SiamFC代码配置复现

    写在前面 最近在研究SiamRPN xff0c 究其根本 xff0c CNN依托于AlexNet骨架 xff0c 所以花些功夫研究以下SiamFC代码 xff0c 将其阶段性复现 Tracking only 关于GPU显卡配置 cudn和c
  • PySOT

    写在前面 期待已久的PySOT终于放上了code xff0c 高兴ing xff0c 赶忙进行相应的配置加以复现 xff0c 不得不说 xff0c 作者真的很贴心 xff0c 把配置环境的指令封装成脚本 xff0c 直接按需配置即可 但是在
  • 【Linux】SocketCan c语言编程

    前言 为了能够对Socket CAN的深入理解 xff0c 我们需要了解Socket的机制 Socket的中文翻译为 插座 xff0c 在计算机世界里称为套接字 Socket最初是作为网络上不同主机之间进程的通信接口 xff0c 后来应用越