如何使用netlink进行IPC?
How to use netlink for IPC?
我的项目需要使用 Netlink 进行 IPC,参考文献是 Netlink unicast. I had done some changes in code. Firstly, I started both receiver and sender, then I inputted the sender's pid to receiver and later inputted receiver's pid to sender. But the receiver didn't receive the message. I also refer Is anyone using netlink for IPC?,其中 none 个正在运行。我的代码有什么问题吗?
收件人代码:
#include <sys/socket.h>
#include <linux/netlink.h>
#include <stdio.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#define NLINK_MSG_LEN 1024
#define NETLINK_USER 31
int main() {
int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
//int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USERSOCK);
//int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
printf("Inside recv main\n");
if (fd < 0) {
printf("Socket creation failed. try again\n");
return -1;
}
/* Declare for src NL sockaddr, dest NL sockaddr, nlmsghdr, iov, msghr */
struct sockaddr_nl src_addr, dest_addr;
memset(&src_addr, 0, sizeof(src_addr));
memset(&dest_addr, 0, sizeof(dest_addr));
//allocate buffer for netlink message which is message header + message payload
struct nlmsghdr *nlh =(struct nlmsghdr *) malloc(NLMSG_SPACE(NLINK_MSG_LEN));
memset(nlh, 0, NLMSG_SPACE(NLINK_MSG_LEN));
//fill the iovec structure
struct iovec iov;
memset(&iov, 0, sizeof(iov));
//define the message header for message
//sending
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
int sender_pid;
printf("Receiver process id: %d\n", getpid());
printf("Sender process id: ");
scanf("%d", &sender_pid);
src_addr.nl_family = AF_NETLINK; //AF_NETLINK socket protocol
src_addr.nl_pid = getpid(); //application unique id
src_addr.nl_groups = 0; //specify not a multicast communication
dest_addr.nl_family = AF_NETLINK; // protocol family
dest_addr.nl_pid = sender_pid; //destination process id
dest_addr.nl_groups = 0;
nlh->nlmsg_len = NLMSG_SPACE(NLINK_MSG_LEN); //netlink message length
nlh->nlmsg_pid = getpid(); //src application unique id
nlh->nlmsg_flags = 0;
iov.iov_base = (void *)nlh; //netlink message header base address
iov.iov_len = nlh->nlmsg_len; //netlink message length
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
//attach socket to unique id or address
if(bind(fd, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) {
printf("Bind failed");
return -1;
}
/* Listen forever in a while loop */
while (1) {
//receive the message
recvmsg(fd, &msg, 0);
printf("Received message: %s\n", (char *)NLMSG_DATA(nlh));
}
close(fd); // close the socket
}
发件人代码:
#include <sys/socket.h>
#include <linux/netlink.h>
#include <stdio.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#define NLINK_MSG_LEN 1024
#define NETLINK_USER 31
int main() {
int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
//int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USERSOCK);
//int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
printf("Inside send main\n");
if (fd < 0) {
printf("Socket creation failed. try again\n");
return -1;
}
/* Declare for src NL sockaddr, dest NL sockaddr, nlmsghdr, iov, msghr */
struct sockaddr_nl src_addr, dest_addr;
memset(&src_addr, 0, sizeof(src_addr));
memset(&dest_addr, 0, sizeof(dest_addr));
//allocate buffer for netlink message which is message header + message payload
struct nlmsghdr *nlh =(struct nlmsghdr *) malloc(NLMSG_SPACE(NLINK_MSG_LEN));
memset(nlh, 0, NLMSG_SPACE(NLINK_MSG_LEN));
//fill the iovec structure
struct iovec iov;
memset(&iov, 0, sizeof(iov));
//define the message header for message
//sending
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
int receiver_pid;
printf("Sender process id: %d\n", getpid());
printf("Receiver process id: ");
scanf("%d", &receiver_pid);
src_addr.nl_family = AF_NETLINK; //AF_NETLINK socket protocol
src_addr.nl_pid = getpid(); //application unique id
src_addr.nl_groups = 0; //specify not a multicast communication
dest_addr.nl_family = AF_NETLINK; // protocol family
dest_addr.nl_pid = receiver_pid; //destination process id
dest_addr.nl_groups = 0;
nlh->nlmsg_len = NLMSG_SPACE(NLINK_MSG_LEN); //netlink message length
nlh->nlmsg_pid = getpid(); //src application unique id
nlh->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nlh), "Hello World !"); //copy the payload to be sent
iov.iov_base = (void *)nlh; //netlink message header base address
iov.iov_len = nlh->nlmsg_len; //netlink message length
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
//attach socket to unique id or address
if(bind(fd, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) {
printf("Bind failed");
return -1;
}
//send the message
sendmsg(fd, &msg, 0);
printf("Send message %s\n", (char *)NLMSG_DATA(nlh));
close(fd); // close the socket
}
您对 socket
使用了错误的协议类型。唯一可以做你想做的,用户-space 进程之间的 IPC,是 NETLINK_USERSOCK
.
请记住,在安排与 PID 的通信时,您可能会错过一些消息...为了验证通信是否发生,您可以留下 msg_name
NULL
对于接收者,这不会产生不良影响 - 这样做并更改协议,您的代码将按预期工作。
我的项目需要使用 Netlink 进行 IPC,参考文献是 Netlink unicast. I had done some changes in code. Firstly, I started both receiver and sender, then I inputted the sender's pid to receiver and later inputted receiver's pid to sender. But the receiver didn't receive the message. I also refer Is anyone using netlink for IPC?,其中 none 个正在运行。我的代码有什么问题吗?
收件人代码:
#include <sys/socket.h>
#include <linux/netlink.h>
#include <stdio.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#define NLINK_MSG_LEN 1024
#define NETLINK_USER 31
int main() {
int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
//int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USERSOCK);
//int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
printf("Inside recv main\n");
if (fd < 0) {
printf("Socket creation failed. try again\n");
return -1;
}
/* Declare for src NL sockaddr, dest NL sockaddr, nlmsghdr, iov, msghr */
struct sockaddr_nl src_addr, dest_addr;
memset(&src_addr, 0, sizeof(src_addr));
memset(&dest_addr, 0, sizeof(dest_addr));
//allocate buffer for netlink message which is message header + message payload
struct nlmsghdr *nlh =(struct nlmsghdr *) malloc(NLMSG_SPACE(NLINK_MSG_LEN));
memset(nlh, 0, NLMSG_SPACE(NLINK_MSG_LEN));
//fill the iovec structure
struct iovec iov;
memset(&iov, 0, sizeof(iov));
//define the message header for message
//sending
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
int sender_pid;
printf("Receiver process id: %d\n", getpid());
printf("Sender process id: ");
scanf("%d", &sender_pid);
src_addr.nl_family = AF_NETLINK; //AF_NETLINK socket protocol
src_addr.nl_pid = getpid(); //application unique id
src_addr.nl_groups = 0; //specify not a multicast communication
dest_addr.nl_family = AF_NETLINK; // protocol family
dest_addr.nl_pid = sender_pid; //destination process id
dest_addr.nl_groups = 0;
nlh->nlmsg_len = NLMSG_SPACE(NLINK_MSG_LEN); //netlink message length
nlh->nlmsg_pid = getpid(); //src application unique id
nlh->nlmsg_flags = 0;
iov.iov_base = (void *)nlh; //netlink message header base address
iov.iov_len = nlh->nlmsg_len; //netlink message length
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
//attach socket to unique id or address
if(bind(fd, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) {
printf("Bind failed");
return -1;
}
/* Listen forever in a while loop */
while (1) {
//receive the message
recvmsg(fd, &msg, 0);
printf("Received message: %s\n", (char *)NLMSG_DATA(nlh));
}
close(fd); // close the socket
}
发件人代码:
#include <sys/socket.h>
#include <linux/netlink.h>
#include <stdio.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#define NLINK_MSG_LEN 1024
#define NETLINK_USER 31
int main() {
int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
//int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USERSOCK);
//int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);
printf("Inside send main\n");
if (fd < 0) {
printf("Socket creation failed. try again\n");
return -1;
}
/* Declare for src NL sockaddr, dest NL sockaddr, nlmsghdr, iov, msghr */
struct sockaddr_nl src_addr, dest_addr;
memset(&src_addr, 0, sizeof(src_addr));
memset(&dest_addr, 0, sizeof(dest_addr));
//allocate buffer for netlink message which is message header + message payload
struct nlmsghdr *nlh =(struct nlmsghdr *) malloc(NLMSG_SPACE(NLINK_MSG_LEN));
memset(nlh, 0, NLMSG_SPACE(NLINK_MSG_LEN));
//fill the iovec structure
struct iovec iov;
memset(&iov, 0, sizeof(iov));
//define the message header for message
//sending
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
int receiver_pid;
printf("Sender process id: %d\n", getpid());
printf("Receiver process id: ");
scanf("%d", &receiver_pid);
src_addr.nl_family = AF_NETLINK; //AF_NETLINK socket protocol
src_addr.nl_pid = getpid(); //application unique id
src_addr.nl_groups = 0; //specify not a multicast communication
dest_addr.nl_family = AF_NETLINK; // protocol family
dest_addr.nl_pid = receiver_pid; //destination process id
dest_addr.nl_groups = 0;
nlh->nlmsg_len = NLMSG_SPACE(NLINK_MSG_LEN); //netlink message length
nlh->nlmsg_pid = getpid(); //src application unique id
nlh->nlmsg_flags = 0;
strcpy(NLMSG_DATA(nlh), "Hello World !"); //copy the payload to be sent
iov.iov_base = (void *)nlh; //netlink message header base address
iov.iov_len = nlh->nlmsg_len; //netlink message length
msg.msg_name = (void *)&dest_addr;
msg.msg_namelen = sizeof(dest_addr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
//attach socket to unique id or address
if(bind(fd, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) {
printf("Bind failed");
return -1;
}
//send the message
sendmsg(fd, &msg, 0);
printf("Send message %s\n", (char *)NLMSG_DATA(nlh));
close(fd); // close the socket
}
您对 socket
使用了错误的协议类型。唯一可以做你想做的,用户-space 进程之间的 IPC,是 NETLINK_USERSOCK
.
请记住,在安排与 PID 的通信时,您可能会错过一些消息...为了验证通信是否发生,您可以留下 msg_name
NULL
对于接收者,这不会产生不良影响 - 这样做并更改协议,您的代码将按预期工作。