Unix CAN-сокет не ждет сообщения - PullRequest
0 голосов
/ 16 октября 2019

У меня есть сокет unix CAN, созданный как показано ниже:

#include <linux/can.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>

int main() {

    struct can_frame _msg;

    struct sockaddr_can addr;
    struct ifreq ifr;

    int _sock_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);

    if (_sock_fd < 0) {
    }

    strcpy(ifr.ifr_name, "can0");
    if (0 != ioctl(_sock_fd, SIOCGIFINDEX, &ifr)) {
    }
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;

    fcntl(_sock_fd, F_SETFL, O_NONBLOCK);

    if (0 != bind(_sock_fd, (struct sockaddr*)&addr, sizeof(addr))) {
    }

    while (1) {
      ssize_t size = 0;
      ssize_t tmp = 0;
      while (size < sizeof(struct can_frame)) {
        tmp = read(_sock_fd, &_msg, sizeof(struct can_frame));
        if (tmp <= 0) {
            printf("0\n");
        }
        size += tmp;
    }
    printf("%x %x %lx\n", _msg.can_id, _msg.can_dlc, *((uint64_t*)_msg.data));

  }
  return 0;
}


Когда я делаю read на этом сокете, я всегда получаю сообщение немедленно, даже если отправитель ничего не отправляет. read всегда читайте дубликат последнего полученного сообщения вместо ожидания следующего. Я выполняю чтение, как показано ниже:

    size_t size = 0;
    while (size < sizeof(struct can_frame)) size += read(_sock_fd, &_msg, sizeof(struct can_frame));

Меня смущает, почему чтение всегда возвращает дублированное сообщение, ожидая следующего. Если я вызываю функцию чтения в цикле с yeld, она порождает миллионы дубликатов одного и того же сообщения, когда отправитель отправляет только одно: candump утилита правильно показывает полученные сообщения. Почему у него такое поведение?

...