МОЖЕТ сокет читать с фреймами поздно - PullRequest
1 голос
/ 10 октября 2019

Я использую сокет CAN linux, созданный как показано ниже:

    ...
    sockaddr_can addr;
    struct ifreq ifr;

    _sock_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);

    if (_sock_fd < 0) {
        throw(std::bad_exception());
    }

    strcpy(ifr.ifr_name, "can0");
    if (0 != ioctl(_sock_fd, SIOCGIFINDEX, &ifr)) {
        throw(std::bad_exception());
    }
    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))) {
        throw(std::bad_exception());
    }
    ...

И затем я использую обычную функцию read для чтения кадров из сети CAN:

int CANSocket::CANRead(canid_t &id, vector<uint8_t> &data) {

    size_t size = 0;

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

    id = _msg.can_id;

    data.clear();
    for (int i = 0; i < _msg.can_dlc; ++i) {
        data.push_back(_msg.data[i]);
    }

    return data.size();
}

Моя проблемачто когда я вызываю свою функцию CANRead, она возвращает кадры, которые составляют около 100 кадров, прежде чем фактический кадр, который я получаю с помощью утилиты candump.

Я использую 5 мс в спящем режиме между кадрами чтения, и сервер отправляет кадры около 25 кадровв секунду.

Например: когда я перечисляю прочитанные кадры утилитой candump, я получаю, например, кадры

101
102
103
104
...
200

, но моя программа, работающая в то же время, возвращает кадры, такие как

1
1
1
2
2
2
...
99

Что я делаю не так в чтении фреймов и конфигурации сокетов, чтобы считывать поздние фреймы с дубликатами?

1 Ответ

1 голос
/ 15 октября 2019

Проблема была вызвана буферизацией чтения сокетов. Установка размера буфера для небольшой решенной проблемы:

    ...
    int bufsize = 128;
    if (0 != setsockopt(_sock_fd, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize))) {
        throw(std::bad_exception());
    }
    ...
...