sockets - 卡在 netlink、connektor、socket 和 co 上
问题描述
我对 netlink & co 完全陌生。我正在尝试建立从用户空间到树莓派的 w1-kernel 模块的连接。不幸的是,我发现的文档参差不齐且相互矛盾。
这里有些事情我不清楚:
基本沟通是:
- 生成一个套接字:socket()
int s = socket(AF_NETLINK,SOCK_DGRAM, NETLINK_CONNECTOR);
- 将其绑定到本地名称:bind()
int b = bind(s,(sockaddr*)&sa,sizeof(sa));
with
sa.nl_family=AF_NETLINK;
sa.nl_pid=getpid();//0?
sa.nl_groups=0; //23? -1?
- 创建消息
- 发送它:发送()?发送消息()?
- 等待答案:poll()
- 阅读答案:recv()
+在我发现的示例(w1d.c 和 ucon.c)中,他们使用send()
没有 connect() 的命令(不是 sendmsg),即使 send 的手册页说这不起作用。
+我不清楚消息的结构:
- send 可以发送任何缓冲区(char*)
- netlink 需要一个 struct nlmsghdr 标头;
- 连接器需要一个 struct cn_msg 标头。
- w1_netlink 需要 w1_netlink_msg 标头和 w1_netlink_cmd 数据。
我需要连续的所有标题吗?有 2 个序列/消息编号变量,一个在 nlmsghdr 中,一个在 cn_msg 中???
我编写的测试程序没有产生我期望的结果:每件事都能产生错误,但我没有得到答案:-(
#include <iostream>
#include <linux/netlink.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<sys/poll.h>
#include <unistd.h>
#include<cstring>
#include "w1_netlink.h"
__u32 nl_seq;
static int netlink_send(int s, struct cn_msg *msg) //copy from (ucon.c)
{
struct nlmsghdr *nlh;
unsigned int size;
int err;
char buf[128];
struct cn_msg *m;
size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
nlh = (struct nlmsghdr *)buf;
nlh->nlmsg_seq = nl_seq++;
nlh->nlmsg_pid = getpid();
nlh->nlmsg_type = NLMSG_DONE;
nlh->nlmsg_len = size;
nlh->nlmsg_flags = 0;
m = (cn_msg*) NLMSG_DATA(nlh);
memcpy(m, msg, sizeof(*m) + msg->len);
err = send(s, nlh, size, 0);
return err;
}
int main(int argc, char *argv[])
{
nl_seq=0;
int s = socket(AF_NETLINK,SOCK_DGRAM, NETLINK_CONNECTOR);
if(s==-1) {std::cout<<"no socket"; return s;};
std::cout<<"socket "<<s;
sockaddr_nl sa;
sa.nl_family=AF_NETLINK;
sa.nl_pid=0;//getpid();
sa.nl_groups=0;
int b = bind(s,(sockaddr*)&sa,sizeof(sa));
if(b==-1){std::cout<<"bind error";return b;}; //prints 3
std::cout<<"bind "<<b; //prints 0
int si=sizeof(struct cn_msg)+sizeof(struct w1_netlink_msg)+sizeof(w1_netlink_cmd);
char * buf;
buf=(char *)malloc(1024);
memset(buf,0,1024);
cn_msg *cnh = (cn_msg*)buf;
w1_netlink_msg* wnh=(w1_netlink_msg*)&cnh->data;
w1_netlink_cmd* wcmd = (w1_netlink_cmd*)&wnh->data;
cnh->id.idx=CN_W1_IDX;
cnh->id.val=CN_W1_VAL;
cnh->seq=nl_seq;
cnh->flags=0;
wnh->type=W1_LIST_MASTERS;
wnh->len=0;
cnh->len=sizeof(struct w1_netlink_msg)+sizeof(w1_netlink_cmd);
int len=netlink_send(s,cnh);
std::cout<<"send "<<len<<" "<<(int)wnh->status; //prints 52 0
pollfd pfd;
pfd.fd=s;
pfd.events=POLLIN;
pfd.revents=0;
int p=0;
while(p<1) {
p=poll(&pfd,1,1000);
std::cout<<"poll "<<p<<pfd.revents; //prints 0 0 in infinite loop
std::cout.flush();
};
memset(wcmd,0,128);
len=recv(s,buf,255,0);
std::cout<<"recv "<<len;
close(s);
return 0;
}
结果是socket 3 bind 0 send 52 0 poll 00 poll 00 ...
谢谢
解决方案
推荐阅读
- postgresql - Use returned value of INSERT ... RETURNING in multiple following inserts
- arangodb - 如何删除 Arango DB 中的嵌套记录
- regex - 记事本++替换为空格
- keycloak - 如何在我的 OIDC 客户端 SP 中让 keycloak IDP 触发 IDP 启动注销
- database - Laravel 5.7 数据库关系不起作用
- laravel - Laravel - updateOrCreate or a sync method?
- angular-schematics - 将集合传递到自定义角度示意图?
- php - 如何知道 phpSpreadsheet 生成的 .xls 文件为何损坏?
- php - 为什么我的 mPDF 的输出功能不能正常工作?
- python - virtualenv 没有匹配的分布