在这个示例中,没有设置socket为非阻塞模式,因此read
和write的
调用会进行阻塞,直到有数据可读或可写。read
调用会等待直到接收到一个CAN帧,而write
调用会等待直到CAN帧被写入到socket的发送缓冲区。
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/can.h>
#include <linux/can/raw.h>
int main() {
int s;
struct sockaddr_can addr;
struct ifreq ifr;
struct can_frame frame;
const char *ifname = "can0"; // 你的CAN接口名称
// 创建socket
if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
// 设置CAN接口名称
std::strcpy(ifr.ifr_name, ifname);
if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
perror("Error getting interface index");
close(s);
return -1;
}
// 绑定socket到CAN接口
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Error binding socket");
close(s);
return -1;
}
// 现在你可以阻塞地读取和写入数据了
// 读取数据示例:
std::cout << "Waiting for CAN frame..." << std::endl;
if (read(s, &frame, sizeof(struct can_frame)) < 0) {
perror("Error reading from socket");
} else {
std::cout << "Received CAN frame with data: " << std::hex << (int)frame.data[0] << std::endl;
}
// 写入数据示例:
frame.can_id = 0x123;
frame.can_dlc = 2;
frame.data[0] = 0x11;
frame.data[1] = 0x22;
std::cout << "Sending CAN frame..." << std::endl;
if (write(s, &frame, sizeof(struct can_frame)) < 0) {
perror("Error writing to socket");
} else {
std::cout << "CAN frame sent" << std::endl;
}
// 关闭socket
close(s);
return 0;
}