当前位置: 首页 > news >正文

网站上传系统做网站有没有前景

网站上传系统,做网站有没有前景,新编网页设计与制作教程,主页制作语言缩写文章目录 1. 前言2. Netlink 范例3. Netlink 简析3.1 Netlink 协议簇注册3.2 创建 用户空间 Netlink 套接字3.3 用户空间 Netlink 套接字 的 绑定3.4 向 内核空间 Netlink 套接字 发消息3.5 从 内核空间 Netlink 套接字 读消息3.5.1 内核空间 Netlink 套接字 向 用户空间 Netli… 文章目录 1. 前言2. Netlink 范例3. Netlink 简析3.1 Netlink 协议簇注册3.2 创建 用户空间 Netlink 套接字3.3 用户空间 Netlink 套接字 的 绑定3.4 向 内核空间 Netlink 套接字 发消息3.5 从 内核空间 Netlink 套接字 读消息3.5.1 内核空间 Netlink 套接字 向 用户空间 Netlink 套接字 发送消息3.5.2 用户空间 Netlink 套接字 读取 内核空间 Netlink 套接字 发送的消息 4. 参考资料 1. 前言 限于作者能力水平本文可能存在谬误因此而给读者带来的损失作者不做任何承诺。 2. Netlink 范例 Netlink 通信包括 内核空间 和 用户空间 两部分具体来讲是两个分别位于 内核空间 和 用户空间 的 AF_NETLINK 协议簇套接字。来看一个具体的例子先看 内核空间 部分 netlink_kern_test.c #include linux/init.h #include linux/module.h #include linux/types.h #include net/sock.h #include linux/netlink.hextern struct net init_net;#define NETLINK_TEST 30 #define MSG_LEN 100 #define USER_PORT 66static struct sock *test_nlsk;int send_usrmsg(char *buf, uint16_t len) {struct sk_buff *nl_skb;struct nlmsghdr *nlh;nl_skb nlmsg_new(len, GFP_ATOMIC);if (!nl_skb) {pr_err(netlink alloc failure\n);return -1;}nlh nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0);if (nlh NULL) {pr_err(nlmsg_put failure\n);nlmsg_free(nl_skb);return -1;}memcpy(nlmsg_data(nlh), buf, len);return netlink_unicast(test_nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); }static void netlink_rcv_msg(struct sk_buff *skb) { struct nlmsghdr *nlh;char *umsg NULL;char *kmsg Hello user process!;nlh nlmsg_hdr(skb);umsg NLMSG_DATA(nlh);if (umsg) {printk(kernel recv msg from user: %s\n, umsg);printk(port id: %d\n, NETLINK_CB(skb).portid);send_usrmsg(kmsg, strlen(kmsg));} }static int __init test_netlink_init(void) {struct netlink_kernel_cfg cfg {.input netlink_rcv_msg,};test_nlsk (struct sock *)netlink_kernel_create(init_net, NETLINK_TEST, cfg);return test_nlsk ? 0 : -1; }static void __exit test_netlink_exit(void) {netlink_kernel_release(test_nlsk); }module_init(test_netlink_init); module_exit(test_netlink_exit);MODULE_LICENSE(GPL);内核 Netlink 示例模块的逻辑很简单调用接口 netlink_kernel_create() 创建一个 Netlink 内核空间套接字且其协议类型为自定的 NETLINK_TEST其数据接收接口为 netlink_rcv_msg() 。当其它 Netlink 套接字向它发送数据时内核调用 netlink_rcv_msg() 处理数据接收此时可通过调用 netlink_unicast() 向数据发送套接字回送数据。 接下来构建一个 Makefile 来编译这个内核模块并安装到系统。Makefile 内容如下 ifneq ($(KERNELRELEASE),)obj-m : netlink_kern_test.oelseKERNELDIR ? /lib/modules/$(shell uname -r)/build PWD : $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M$(PWD) modulesendifclean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions .cache.mk modules.order Module.symvers$ make $ sudo insmod netlink_kern_test.ko再看 Netlink 示例的用户控件部分 netlink_user_test.c #include stdio.h #include stdlib.h #include sys/socket.h #include string.h #include linux/netlink.h #include stdint.h #include unistd.h#define NETLINK_TEST 30 #define USER_PORT 66#define MSG_LEN 100 #define MAX_PLOAD 200struct netlink_user_msg {struct nlmsghdr hdr;char msg[MSG_LEN]; };int main(int argc,char **argv) {int sockfd;struct sockaddr_nl saddr, daddr;struct nlmsghdr *nlh;struct netlink_user_msg u_info;char *msg Hello kernel, I am a user process!;socklen_t len;// 创建 Netlink 用户空间套接字sockfd socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST);if (sockfd 0) {perror(socket);return -1;}// 数据 源 Netlink 套接字 地址memset(saddr, 0, sizeof(saddr));saddr.nl_family AF_NETLINK;saddr.nl_pad 0;saddr.nl_pid USER_PORT; // 端口号saddr.nl_groups 0;if (bind(sockfd, (struct sockaddr *)saddr, sizeof(saddr)) 0) {perror(socket);return -1;}// Netlink 消息数据nlh (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PLOAD));memset(nlh, 0, sizeof(struct nlmsghdr));nlh-nlmsg_len NLMSG_SPACE(MAX_PLOAD);nlh-nlmsg_flags 0;nlh-nlmsg_type 0;nlh-nlmsg_seq 0;nlh-nlmsg_pid saddr.nl_pid;memcpy(NLMSG_DATA(nlh), msg, strlen(msg));// 数据 目的 Netlink 套接字 地址memset(daddr, 0, sizeof(daddr));daddr.nl_family AF_NETLINK;daddr.nl_pid 0; /* 0 表示数据发往 内核空间 Netlink 套接字 */daddr.nl_groups 0;sendto(sockfd, nlh, nlh-nlmsg_len, 0, (struct sockaddr *)daddr, sizeof(struct sockaddr_nl));printf(send kernel: %s, msg);// 从内核 Netlink 套接字接收数据memset(daddr, 0, sizeof(daddr));memset(u_info, 0, sizeof(u_info));len sizeof(struct sockaddr_nl);recvfrom(sockfd, u_info, sizeof(user_msg_info), 0, (struct sockaddr *)daddr, len);printf(\n);printf(from kernel(%u): %s\n, daddr.nl_pid, u_info.msg);close(sockfd);return 0; }编译执行用户空间测试程序 netlink_user_test $ make netlink_user_test $ ./netlink_user_test本文示例是 内核空间 和 用户空间 Netlink 套接字通信事实上内核空间的 Netlink 相互之间也可以通信而且 Netlink 不仅支持单播通信还支持广播通信本文对此不做展开。 3. Netlink 简析 本文就示例中 内核空间 和 用户空间 Netlink 套接字通信做简单分析。 3.1 Netlink 协议簇注册 static struct proto netlink_proto {.name NETLINK,.owner THIS_MODULE,.obj_size sizeof(struct netlink_sock), };static const struct net_proto_family netlink_family_ops {.family PF_NETLINK,.create netlink_create, /* 创建 用户空间 netlink 套接字 */.owner THIS_MODULE, /* for consistency 8) */ };static int __init netlink_proto_init(void) {int err proto_register(netlink_proto, 0);...nl_table kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL);...// Netlink 协议簇 PF_NETLINK 注册sock_register(netlink_family_ops);... }core_initcall(netlink_proto_init);3.2 创建 用户空间 Netlink 套接字 sockfd socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST); /* net/socket.c */retval sock_create(family, type, protocol, sock);__sock_create(current-nsproxy-net_ns, family, type, protocol, res, 0);sock sock_alloc();...sock-type type; // SOCK_RAW...pf rcu_dereference(net_families[family]);...err pf-create(net, sock, protocol, kern);netlink_create() /* net/netlink/af_netlink.c */...err __netlink_create(net, sock, cb_mutex, protocol, kern);...sock-ops netlink_ops;sk sk_alloc(net, PF_NETLINK, GFP_KERNEL, netlink_proto, kern);...sk-sk_destruct netlink_sock_destruct;sk-sk_protocol protocol; // NETLINK_TESTretval sock_map_fd(sock, flags (O_CLOEXEC | O_NONBLOCK));3.3 用户空间 Netlink 套接字 的 绑定 struct sockaddr_nl saddr;memset(saddr, 0, sizeof(saddr)); saddr.nl_family AF_NETLINK; saddr.nl_pad 0; saddr.nl_pid USER_PORT; saddr.nl_groups 0; bind(sockfd, (struct sockaddr *)saddr, sizeof(saddr))struct socket *sock;sock sockfd_lookup_light(fd, err, fput_needed);.../* 拷贝用户参数到内核空间: umyaddr address */err move_addr_to_kernel(umyaddr, addrlen, address);...err sock-ops-bind(sock, (struct sockaddr *)address, addrlen);netlink_bind() /* net/netlink/af_netlink.c */bool bound;...bound nlk-bound;...if (!bound) { /* 还没有对 netlink 套接字进行过绑定 */...netlink_insert(sk, nladdr-nl_pid)...nlk_sk(sk)-portid portid; /* 设定 netlink 套接字绑定的端口号 */.../** 将 sk 插入到 netlink 协议类型 sk-sk_protocol* 对应表项 nl_table[sk-sk_protocol] 的 sock 列表。* sk-sk_protocol {NETLINK_ROUTE, ...}*/err __netlink_insert(table, sk);.../** 标记 netlink 套接字 sk 已经进行了 地址 和 端口 的绑定, * 即已经调用过了 bind().*/smp_wmb();nlk_sk(sk)-bound portid;}3.4 向 内核空间 Netlink 套接字 发消息 struct sockaddr_nl daddr; struct nlmsghdr *nlh;nlh (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PLOAD)); // 分配 头部 内容 空间 并对齐到 4 字节memset(nlh, 0, sizeof(struct nlmsghdr)); nlh-nlmsg_len NLMSG_SPACE(MAX_PLOAD); nlh-nlmsg_flags 0; nlh-nlmsg_type 0; nlh-nlmsg_seq 0; nlh-nlmsg_pid saddr.nl_pid; // 指定 源端口号 USER_PORT memcpy(NLMSG_DATA(nlh), msg, strlen(msg)); // 设置消息内容// 设置消息发往的 目标 内核空间 netlink 套接字 地址 memset(daddr, 0, sizeof(daddr)); daddr.nl_family AF_NETLINK; daddr.nl_pid 0; // 发往内核 Netlink 套接字 daddr.nl_groups 0;// 往 目标内核 netlink 套接字 发消息 sendto(sockfd, nlh, nlh-nlmsg_len, 0, (struct sockaddr *)daddr, sizeof(struct sockaddr_nl));struct socket *sock;...struct msghdr msg;...err import_single_range(WRITE, buff, len, iov, msg.msg_iter);...sock sockfd_lookup_light(fd, err, fput_needed);...msg.msg_name NULL;msg.msg_control NULL;msg.msg_controllen 0;msg.msg_namelen 0;err move_addr_to_kernel(addr, addr_len, address);msg.msg_name (struct sockaddr *)address;msg.msg_namelen addr_len;...msg.msg_flags flags;err sock_sendmsg(sock, msg);sock_sendmsg_nosec(sock, msg);int ret sock-ops-sendmsg(sock, msg, msg_data_left(msg));netlink_sendmsg() /* net/netlink/af_netlink.c */...if (msg-msg_namelen) {.../** dst_portid: 数据发往的 目标 netlink 套接字端口号* dst_group : 数据发往的 目标 netlink 套接字 组*/dst_portid addr-nl_pid;dst_group ffs(addr-nl_groups);...netlink_skb_flags | NETLINK_SKB_DST;} else {...}...skb netlink_alloc_large_skb(len, dst_group); /* 分配 skb, 准备用来接收来自 sock 的数据 */...NETLINK_CB(skb).portid nlk-portid; /* 设定 skb 的数据 源端口号 */NETLINK_CB(skb).dst_group dst_group; /* 设定 skb 的数据 目标组 */...NETLINK_CB(skb).flags netlink_skb_flags; // | NETLINK_SKB_DST...if (memcpy_from_msg(skb_put(skb, len), msg, len)) { /* 将要发送的数据 msg 拷贝到 skb */...}...err netlink_unicast(sk, skb, dst_portid, msg-msg_flagsMSG_DONTWAIT); /* netlink 单播 */...retry: /* * 目标 sock (sk) 是 内核 sock, 如情形:* data* 用户空间 netlink 套接字 ssk ---- 内核空间 netlink 套接字 sk*/sk netlink_getsockbyportid(ssk, portid);...if (netlink_is_kernel(sk))netlink_unicast_kernel()nlk-netlink_rcv(skb)recv_msg_from_user_land()3.5 从 内核空间 Netlink 套接字 读消息 从 内核空间 Netlink 套接字 读消息 这分为两步 1. 内核空间 Netlink 套接字 向 用户空间 Netlink 套接字 发送消息 2. 用户空间 Netlink 套接字 读取 内核空间 Netlink 套接字 发送的消息3.5.1 内核空间 Netlink 套接字 向 用户空间 Netlink 套接字 发送消息 #define USER_PORT 66 // 用户空间 netlink 套接字 端口号struct sk_buff *nl_skb; struct nlmsghdr *nlh;// 构建 skb: 容纳 消息头部 len 长度的数据 nl_skb nlmsg_new(len, GFP_ATOMIC);// 设置源消息头部: 协议类型、端口号、数据长度等 nlh nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0);__nlmsg_put(skb, portid, seq, type, payload, flags); // portid 0, 指代内核 netlink 套接字struct nlmsghdr *nlh;int size nlmsg_msg_size(len);nlh skb_put(skb, NLMSG_ALIGN(size));nlh-nlmsg_type type;nlh-nlmsg_len size;nlh-nlmsg_flags flags;nlh-nlmsg_pid portid;nlh-nlmsg_seq seq;// 填充要发送的数据内容 memcpy(nlmsg_data(nlh), buf, len);netlink_unicast(test_nlsk, nl_skb, USER_PORT, MSG_DONTWAIT); // 将数据发送 用户空间 netlink 套接字... retry: /* * 用 * {sock_net(ssk), ssk-sk_protocol, portid}* 寻找目标 netlink sock, 数据传输方向: * ssk (源sock) - sk (目标sock)*/sk netlink_getsockbyportid(ssk, portid);.../* * 目标 sock (sk) 是 用户空间 sock, 如情形:* data* 内核空间 netlink 套接字 ssk ---- 用户空间 netlink 套接字 sk*/return netlink_sendskb(sk, skb);int len __netlink_sendskb(sk, skb);.../* 将数据添加到 目标 sk 的 接收 skb 队列 */skb_queue_tail(sk-sk_receive_queue, skb);/* 唤醒 可能的、因等待读取数据 而睡眠的进程 */sk-sk_data_ready(sk);sock_def_readable()3.5.2 用户空间 Netlink 套接字 读取 内核空间 Netlink 套接字 发送的消息 struct netlink_user_msg {struct nlmsghdr hdr;char msg[MSG_LEN]; };struct sockaddr_nl daddr; struct netlink_user_msg u_info;memset(u_info, 0, sizeof(u_info)); len sizeof(struct sockaddr_nl); recvfrom(sockfd, u_info, sizeof(user_msg_info), 0, (struct sockaddr *)daddr, len);...err import_single_range(READ, ubuf, size, iov, msg.msg_iter);...sock sockfd_lookup_light(fd, err, fput_needed);msg.msg_control NULL;msg.msg_controllen 0;/* Save some cycles and dont copy the address if not needed */msg.msg_name addr ? (struct sockaddr *)address : NULL;/* We assume all kernel code knows the size of sockaddr_storage */msg.msg_namelen 0;msg.msg_iocb NULL;msg.msg_flags 0;...err sock_recvmsg(sock, msg, flags);sock_recvmsg_nosec(sock, msg, flags);sock-ops-recvmsg(sock, msg, msg_data_left(msg), flags);netlink_recvmsg() /* net/netlink/af_netlink.c */.../** 从 sk 的接收队列 sk-sk_receive_queue 取就绪的数据 skb.* 阻塞模式下, 可因没有数据而陷入睡眠等待.*/skb skb_recv_datagram(sk, flags, noblock, err);...data_skb skb; /* 返回就绪的 skb */.../* 这里告诉我们, netlink 协议数据位于 传输层(L4) 之上, 即位于 应用层(L5) */skb_reset_transport_header(data_skb);err skb_copy_datagram_msg(data_skb, 0, msg, copied); /* 从就绪的 skb 读取数据 */if (msg-msg_name) {DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg-msg_name);addr-nl_family AF_NETLINK;addr-nl_pad 0;addr-nl_pid NETLINK_CB(skb).portid;addr-nl_groups netlink_group_mask(NETLINK_CB(skb).dst_group);msg-msg_namelen sizeof(*addr);}...4. 参考资料 [1] Introduction to Netlink
http://www.pierceye.com/news/731553/

相关文章:

  • 校园文化建设图片网站浅析图书馆门户网站建设
  • 网站开发与应用案例教程哈尔滨自助建站系统
  • 网站关键词排名seo百度网址链接是多少
  • 电子商务网站的建设收益直播软件的app
  • 遵义在百度做个网站多少钱如何建立企业网站
  • 我想做个网站手机网站建设优势
  • 网站制作毕业设计滁州市建设局网站
  • saas建站和开源建站的区别比较高端的网页
  • 新公司董事长致辞做网站wordpress二次开发手册chm
  • 网站显示建设中大型企业网站制作
  • 长沙自动化网站建设wordpress 自定义栏目 调用
  • 吉大建设工程学院官方网站wordpress 文章图片插件
  • 赤峰中国建设招标网站网页设计素材网站推荐
  • 天津网站建设电焊机wordpress主题jenney
  • 个人网站制作wordpress英文注册查询网站
  • 哪里有免费网站空间申请wordpress重定向插件
  • 福州微网站开发什么样的网站快速盈利
  • 吉首市建设局官方网站一对一直播软件开发定制
  • 网站开发验收单做的网站如何被百度搜到
  • 网站的数据库是什么两学一做网站链接
  • 做窗帘网站济南网络科技公司排名
  • 广东省住房城乡建设部网站哪个网站可以做加工代理的
  • dede网站源码打包下载wordpress登不进后台
  • 建设内部网站目的国内贸易在那个网站上做
  • 用什么建设网站注册深圳公司代理
  • 网站平台建设方案书百度云资源搜索入口
  • 网站 团队博罗网站建设哪家便宜
  • wordpress列表分页枣庄seo外包
  • 知了网站后台推广形式有哪几种
  • 成品图片的网站在哪里找wordpress开启防盗链