Информация, которую я собрал о многоадресной рассылке netlink, находится вся между ядром и пользовательским пространством.
Хотя я знаю, что это, возможно, лучший способ использовать общую память в моей ситуации, мне нужно использовать Netlink для многоадресной передачи IPC между пользовательским пространством и пользовательским пространством. Я уже создал демо-версию с получателем и отправителем Netlink, но столкнулся с некоторыми проблемами из-за моего ограниченного понимания Netlink.
Вот моя простая демонстрация netlink для приемника:
#include #include #include #include #include #include #include #include #include #define NLINK_MSG_LEN 1024 интервал основной() { // Вопрос: // когда я использую `NETLINK_USERSOCK` в программе-получателе, система сообщает // у меня недостаточно прав для привязки fd, и мне приходится использовать sudo, но я // предпочитаю этого не делать. int fd =::socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); printf("приемник готов!\n"); если (fd < 0) { perror("Не удалось создать сокет Netlink!\n"); выход (1); } структура sockaddr_nl Listen_addr; Listen_addr.nl_family = AF_NETLINK; // Протокол сокета AF_NETLINK Listen_addr.nl_pid = getpid(); // уникальный идентификатор приложения Listen_addr.nl_groups = (1 nlmsg_len = NLMSG_SPACE(NLINK_MSG_LEN); nlh->nlmsg_pid = getpid(); nlh->nlmsg_flags = 0; структура iovec iov; iov.iov_base = reinterpret_cast(nlh); iov.iov_len = nlh->nlmsg_len; // мы можем получить адрес отправителя из sender_addr структура sockaddr_nl sender_addr; структура msghdr msg; msg.msg_name = reinterpret_cast(&sender_addr); msg.msg_namelen = sizeof(sender_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; // пытаемся получить сообщение по сетевой ссылке в то время как (1) { ssize_t bytes_received = ::recvmsg(fd, &msg, 0); если (bytes_received == -1) { perror("Не удалось получить сообщение\n"); } еще если (bytes_received == 0) { printf("соединение закрыто удаленным узлом\n"); } еще { printf("получить сообщение от [%u]\n", sender_addr.nl_pid); printf("получить сообщение: %s\n", reinterpret_cast(NLMSG_DATA(nlh))); } } закрыть (ФД); } моя демо-версия для отправителя:
#include #include #include #include #include #include #include #include #include constexpr uint32_t NLINK_MSG_LEN = 1024; интервал основной() { // **Вопрос**: когда я использую `NETLINK_GENERIC` в программе-отправителе, система // сообщает мне, что у меня недостаточно прав для отправки сообщения, и мне приходится использовать // sudo, но я предпочитаю этого не делать. int fd =::socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); printf("Отправитель готов!\n"); если (fd < 0) { perror("Не удалось создать сокет Netlink!"); выход (1); } структура sockaddr_nl dest_addr; dest_addr.nl_family = AF_NETLINK; // **Вопрос**: Интернет-рекомендации предлагают использовать идентификатор процесса в качестве // nl_pid, но я не могу получить идентификатор процесса получателя. Есть ли способ // настроить только nl_groups, чтобы все получатели в этих nl_groups могли // получать сообщения? // // Более того, что странно, даже если я произвольно задам число для // здесь nl_pid, хотя он выдает ошибку «Соединение отклонено», все // получатели в nl_groups все еще могут получать сообщения. dest_addr.nl_pid = 100; dest_addr.nl_groups = (1 nlmsg_len = NLMSG_SPACE(NLINK_MSG_LEN); nlh->nlmsg_pid = getpid(); nlh->nlmsg_flags = 0; структура iovec iov; iov.iov_base = reinterpret_cast(nlh); iov.iov_len = nlh->nlmsg_len; структура msghdr msg; msg.msg_name = reinterpret_cast(&dest_addr); msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; // Отправить сообщение ::memcpy(reinterpret_cast(NLMSG_DATA(nlh)), "Hello World!", 14); ssize_t bytes_sent = ::sendmsg(fd, &msg, 0); printf("pid отправителя [%u]\n", getpid()); если (bytes_sent == -1) { perror("Ошибка отправки сообщения\n"); } еще { printf("отправить сообщение [%s]\n", reinterpret_cast(NLMSG_DATA(nlh))); } ::закрыть(ФД); // закрываем сокет } Вот мои несколько вопросов, некоторые из них уже подняты в демо-коде.
Вопрос 1
Я не хочу требовать разрешения sudo для выполнения кода. Однако когда я использую NETLINK_USERSOCK в получателе или NETLINK_GENERIC в отправителе, мне запрашивается недостаточность разрешений.
Вопрос 2
Я хочу отправлять сообщения всем получателям, соответствующим nl_groups в коде отправителя, без указания dest_addr.nl_pid.
Более того, странно, что программа-отправитель может отправить все получателю nl_groups, но это вызовет проблему Соединение отклонено.

Вопрос 3
Если по моему коду возникнут какие-либо вопросы, дайте мне знать, спасибо~