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

简要说明网站建设的基本流程品牌宣传推广方案

简要说明网站建设的基本流程,品牌宣传推广方案,如何进行营销型企业网站的优化,备案期间网站能访问吗文章目录 前言一、获取本机网关 ip 地址1.1 代码示例1.2 代码详解介绍 二、使用Netlink套接字实时监控网络事件2.1 简介2.2 示例代码 前言 这篇文章写了获取本机的ip地址和子网掩码:Linux c语言获取本机 ip、子网掩码 一、获取本机网关 ip 地址 使用Netlink套接字…

文章目录

  • 前言
  • 一、获取本机网关 ip 地址
    • 1.1 代码示例
    • 1.2 代码详解介绍
  • 二、使用Netlink套接字实时监控网络事件
    • 2.1 简介
    • 2.2 示例代码

前言

这篇文章写了获取本机的ip地址和子网掩码:Linux c语言获取本机 ip、子网掩码

一、获取本机网关 ip 地址

使用Netlink套接字从Linux内核的路由表中检索默认网关IP地址。

关于Netlink套接字请参考:Linux 网络之netlink 简介

1.1 代码示例

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <unistd.h>#define BUFSIZE 8192struct nlreq {struct nlmsghdr hdr;struct rtmsg msg;
};int main(void) 
{int sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);if (sockfd == -1) {perror("socket error");exit(1);}struct sockaddr_nl sa;memset(&sa, 0, sizeof(sa));sa.nl_family = AF_NETLINK;if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {perror("bind error");exit(1);}struct nlreq req;memset(&req, 0, sizeof(req));req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));req.hdr.nlmsg_type = RTM_GETROUTE;req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;req.msg.rtm_family = AF_INET;req.msg.rtm_table = RT_TABLE_MAIN;req.msg.rtm_protocol = RTPROT_UNSPEC;req.msg.rtm_scope = RT_SCOPE_UNIVERSE;req.msg.rtm_type = RTN_UNICAST;struct iovec iov;memset(&iov, 0, sizeof(iov));iov.iov_base = &req;iov.iov_len = req.hdr.nlmsg_len;struct msghdr msg;memset(&msg, 0, sizeof(msg));msg.msg_name = &sa;msg.msg_namelen = sizeof(sa);msg.msg_iov = &iov;msg.msg_iovlen = 1;char buf[BUFSIZE];memset(buf, 0, sizeof(buf));struct nlmsghdr *hdr;int len;if (sendmsg(sockfd, &msg, 0) == -1) {perror("sendmsg error");exit(1);}while ((len = recv(sockfd, buf, sizeof(buf), 0)) > 0) {for (hdr = (struct nlmsghdr *) buf; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) {if (hdr->nlmsg_type == NLMSG_DONE) {goto finish;}if (hdr->nlmsg_type == NLMSG_ERROR) {perror("NLMSG_ERROR");exit(1);}struct rtmsg *rt = (struct rtmsg *) NLMSG_DATA(hdr);if (rt->rtm_family != AF_INET || rt->rtm_table != RT_TABLE_MAIN || rt->rtm_type != RTN_UNICAST) {continue;}struct rtattr *attr;int attrlen;for (attr = (struct rtattr *) RTM_RTA(rt), attrlen = RTM_PAYLOAD(hdr); RTA_OK(attr, attrlen); attr = RTA_NEXT(attr, attrlen)) {if (attr->rta_type == RTA_GATEWAY) {char gw_addr[INET_ADDRSTRLEN];struct in_addr addr;memcpy(&addr, RTA_DATA(attr), sizeof(addr));if (inet_ntop(AF_INET, &addr, gw_addr, sizeof(gw_addr)) == NULL) {perror("inet_ntop error");continue;}printf("Gateway address: %s\n", gw_addr);goto finish;}}}}
finish:close(sockfd);return 0;
}

首先,它使用socket()函数创建一个Netlink套接字,并使用bind()将其绑定到本地地址。然后,它使用nlreq结构体变量初始化Netlink消息的参数。消息请求使用RTM_GETROUTE类型检索路由表,并指定要检索的路由的地址族、表、协议、范围和类型。消息还指定了NLM_F_DUMP标志以检索所有可用路由。

消息使用sendmsg()发送到内核,并使用recv()接收。接收到的数据通过一个循环解析缓冲区中的Netlink消息。该循环跳过与IPv4单播路由和主表无关的消息。对于每个相关消息,它使用另一个循环迭代路由属性,并检索网关地址(如果存在)。网关地址使用printf()打印到控制台,并使用goto语句退出循环。

1.2 代码详解介绍

(1)使用socket函数创建一个Netlink套接字

int sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (sockfd == -1) {perror("socket error");exit(1);
}
/* Protocol families.  */
#define	PF_NETLINK	16/* Address families.  */
#define	AF_NETLINK	PF_NETLINK
/* Types of sockets.  */
enum __socket_type
{SOCK_RAW = 3,			/* Raw protocol interface.  */
#define SOCK_RAW SOCK_RAW
};
#define NETLINK_ROUTE		0	/* Routing/device hook				*/

(2)绑定套接字到本地地址

struct sockaddr_nl sa;
memset(&sa, 0, sizeof(sa));
sa.nl_family = AF_NETLINK;
if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {perror("bind error");exit(1);
}

绑定套接字到本地地址。这是为了确保接收到内核发送的Netlink消息。

(3)创建一个Netlink消息

struct nlreq req;
memset(&req, 0, sizeof(req));
req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req.hdr.nlmsg_type = RTM_GETROUTE;
req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
req.msg.rtm_family = AF_INET;
req.msg.rtm_table = RT_TABLE_MAIN;
req.msg.rtm_protocol = RTPROT_UNSPEC;
req.msg.rtm_scope = RT_SCOPE_UNIVERSE;
req.msg.rtm_type = RTN_UNICAST;

创建一个Netlink消息,用于向内核请求路由表。我们设置消息头部的长度、类型和标志,以及rtmsg结构体的成员。这里我们只请求主路由表中的单播路由表项,以获取默认网关的地址。

(4)将req结构体打包成一个iovec结构体

struct iovec iov;
memset(&iov, 0, sizeof(iov));
iov.iov_base = &req;
iov.iov_len = req.hdr.nlmsg_len;struct msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_name = &sa;
msg.msg_namelen = sizeof(sa);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;

将req结构体打包成一个iovec结构体,用于在消息中发送。我们还创建了一个msghdr结构体,指定发送和接收消息的参数。

(5)使用sendmsg函数将消息发送到内核

if (sendmsg(sockfd, &msg, 0) == -1) {perror("sendmsg error");exit(1);
}

(6)使用recv函数从内核接收消息

char buf[BUFSIZE];
memset(buf, 0, sizeof(buf));
struct nlmsghdr *hdr;
int len;
if (sendmsg(sockfd, &msg, 0) == -1) {perror("sendmsg error");exit(1);
}
while ((len = recv(sockfd, buf, sizeof(buf), 0)) > 0) {for (hdr = (struct nlmsghdr *) buf; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) {if (hdr->nlmsg_type == NLMSG_DONE) {goto finish;}if (hdr->nlmsg_type == NLMSG_ERROR) {perror("NLMSG_ERROR");exit(1);}// 解析路由表项}
}

使用recv函数从内核接收消息,并使用NLMSG_OK、NLMSG_NEXT和NLMSG_DATA宏来循环遍历消息中的所有路由表项。

(7)获取默认网关的地址

struct rtmsg *rt = (struct rtmsg *) NLMSG_DATA(hdr);
if (rt->rtm_family != AF_INET || rt->rtm_table != RT_TABLE_MAIN || rt->rtm_type != RTN_UNICAST) {continue;
}
struct rtattr *attr;
int attrlen;
for (attr = (struct rtattr *) RTM_RTA(rt), attrlen = RTM_PAYLOAD(hdr); RTA_OK(attr, attrlen); attr = RTA_NEXT(attr, attrlen)) {if (attr->rta_type == RTA_GATEWAY) {char gw_addr[INET_ADDRSTRLEN];struct in_addr addr;memcpy(&addr, RTA_DATA(attr), sizeof(addr));if (inet_ntop(AF_INET, &addr, gw_addr, sizeof(gw_addr)) == NULL) {perror("inet_ntop error");continue;}printf("Gateway address: %s\n", gw_addr);goto finish;}
}
finish:close(sockfd);return 0;
}
/* Routing message attributes */enum rtattr_type_t {RTA_GATEWAY,
};

检查每个路由表项的类型和成员,以确定是否找到了默认网关的地址。如果找到了,使用inet_ntop函数将地址转换为可读形式,并打印它。

二、使用Netlink套接字实时监控网络事件

2.1 简介

可以使用Netlink套接字实时监控网络事件。Netlink是一种基于套接字的接口,用于与Linux内核通信。内核中的各个子系统都使用Netlink与用户空间应用程序通信,包括网络子系统。

网络子系统使用Netlink在某些网络事件发生时向用户空间应用程序发送消息,例如添加或删除网络接口、更改网络路由和更改网络地址。这些消息可以被用户空间应用程序用于实时监控网络事件。

要使用Netlink实时监控网络事件,您需要创建一个Netlink套接字,将其绑定到特定的Netlink协议,然后使用recv函数从内核接收Netlink消息。然后,您可以解析消息以提取有关已发生的网络事件的信息。

2.2 示例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>#define BUFFER_SIZE 4096int main(int argc, char *argv[]) {int netlinkSocket = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);if (netlinkSocket < 0) {perror("创建Netlink套接字失败");exit(EXIT_FAILURE);}struct sockaddr_nl addr;memset(&addr, 0, sizeof(addr));addr.nl_family = AF_NETLINK;addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;if (bind(netlinkSocket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {perror("将Netlink套接字绑定到地址失败");close(netlinkSocket);exit(EXIT_FAILURE);}char buffer[BUFFER_SIZE];struct iovec iov = { buffer, sizeof(buffer) };struct msghdr msg = { (void *)&addr, sizeof(addr), &iov, 1, NULL, 0, 0 };while (1) {ssize_t len = recvmsg(netlinkSocket, &msg, 0);if (len < 0) {perror("接收Netlink消息失败");close(netlinkSocket);exit(EXIT_FAILURE);}struct nlmsghdr *nlh;for (nlh = (struct nlmsghdr *)buffer; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) {switch(nlh->nlmsg_type) {case RTM_NEWLINK:printf("检测到新链接\n");break;case RTM_DELLINK:printf("链接已删除\n");break;case RTM_NEWADDR:printf("检测到新地址\n");break;case RTM_DELADDR:printf("地址已删除\n");break;default:printf("未知的消息类型 (%d)\n", nlh->nlmsg_type);break;}}}close(netlinkSocket);return 0;
}

在一个终端上编译程序并运行。

在另一个终端上输入以下命令来更改网络接口的状态:

sudo ifconfig eth0 down
sudo ifconfig eth0 up

这只是一个简单的示例,可以使用Netlink监控许多其他类型的网络事件。

rtnetlink.h头文件提供了所有可能的Netlink消息类型的列表,可以用于监控其他类型的网络事件。
如下所示:

/*****		Routing/neighbour discovery messages.****//* Types of messages */enum {RTM_BASE	= 16,
#define RTM_BASE	RTM_BASERTM_NEWLINK	= 16,
#define RTM_NEWLINK	RTM_NEWLINKRTM_DELLINK,
#define RTM_DELLINK	RTM_DELLINKRTM_GETLINK,
#define RTM_GETLINK	RTM_GETLINKRTM_SETLINK,
#define RTM_SETLINK	RTM_SETLINKRTM_NEWADDR	= 20,
#define RTM_NEWADDR	RTM_NEWADDRRTM_DELADDR,
#define RTM_DELADDR	RTM_DELADDRRTM_GETADDR,
#define RTM_GETADDR	RTM_GETADDRRTM_NEWROUTE	= 24,
#define RTM_NEWROUTE	RTM_NEWROUTERTM_DELROUTE,
#define RTM_DELROUTE	RTM_DELROUTERTM_GETROUTE,
#define RTM_GETROUTE	RTM_GETROUTERTM_NEWNEIGH	= 28,
#define RTM_NEWNEIGH	RTM_NEWNEIGHRTM_DELNEIGH,
#define RTM_DELNEIGH	RTM_DELNEIGHRTM_GETNEIGH,
#define RTM_GETNEIGH	RTM_GETNEIGHRTM_NEWRULE	= 32,
#define RTM_NEWRULE	RTM_NEWRULERTM_DELRULE,
#define RTM_DELRULE	RTM_DELRULERTM_GETRULE,
#define RTM_GETRULE	RTM_GETRULERTM_NEWQDISC	= 36,
#define RTM_NEWQDISC	RTM_NEWQDISCRTM_DELQDISC,
#define RTM_DELQDISC	RTM_DELQDISCRTM_GETQDISC,
#define RTM_GETQDISC	RTM_GETQDISCRTM_NEWTCLASS	= 40,
#define RTM_NEWTCLASS	RTM_NEWTCLASSRTM_DELTCLASS,
#define RTM_DELTCLASS	RTM_DELTCLASSRTM_GETTCLASS,
#define RTM_GETTCLASS	RTM_GETTCLASSRTM_NEWTFILTER	= 44,
#define RTM_NEWTFILTER	RTM_NEWTFILTERRTM_DELTFILTER,
#define RTM_DELTFILTER	RTM_DELTFILTERRTM_GETTFILTER,
#define RTM_GETTFILTER	RTM_GETTFILTERRTM_NEWACTION	= 48,
#define RTM_NEWACTION   RTM_NEWACTIONRTM_DELACTION,
#define RTM_DELACTION   RTM_DELACTIONRTM_GETACTION,
#define RTM_GETACTION   RTM_GETACTIONRTM_NEWPREFIX	= 52,
#define RTM_NEWPREFIX	RTM_NEWPREFIXRTM_GETMULTICAST = 58,
#define RTM_GETMULTICAST RTM_GETMULTICASTRTM_GETANYCAST	= 62,
#define RTM_GETANYCAST	RTM_GETANYCASTRTM_NEWNEIGHTBL	= 64,
#define RTM_NEWNEIGHTBL	RTM_NEWNEIGHTBLRTM_GETNEIGHTBL	= 66,
#define RTM_GETNEIGHTBL	RTM_GETNEIGHTBLRTM_SETNEIGHTBL,
#define RTM_SETNEIGHTBL	RTM_SETNEIGHTBLRTM_NEWNDUSEROPT = 68,
#define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPTRTM_NEWADDRLABEL = 72,
#define RTM_NEWADDRLABEL RTM_NEWADDRLABELRTM_DELADDRLABEL,
#define RTM_DELADDRLABEL RTM_DELADDRLABELRTM_GETADDRLABEL,
#define RTM_GETADDRLABEL RTM_GETADDRLABELRTM_GETDCB = 78,
#define RTM_GETDCB RTM_GETDCBRTM_SETDCB,
#define RTM_SETDCB RTM_SETDCBRTM_NEWNETCONF = 80,
#define RTM_NEWNETCONF RTM_NEWNETCONFRTM_GETNETCONF = 82,
#define RTM_GETNETCONF RTM_GETNETCONFRTM_NEWMDB = 84,
#define RTM_NEWMDB RTM_NEWMDBRTM_DELMDB = 85,
#define RTM_DELMDB RTM_DELMDBRTM_GETMDB = 86,
#define RTM_GETMDB RTM_GETMDBRTM_NEWNSID = 88,
#define RTM_NEWNSID RTM_NEWNSIDRTM_DELNSID = 89,
#define RTM_DELNSID RTM_DELNSIDRTM_GETNSID = 90,
#define RTM_GETNSID RTM_GETNSIDRTM_NEWSTATS = 92,
#define RTM_NEWSTATS RTM_NEWSTATSRTM_GETSTATS = 94,
#define RTM_GETSTATS RTM_GETSTATS__RTM_MAX,
#define RTM_MAX		(((__RTM_MAX + 3) & ~3) - 1)
};
http://www.ds6.com.cn/news/40168.html

相关文章:

  • 选择热门网站做推广的原因新闻媒体发稿平台
  • 校园网站的系统建设品牌seo主要做什么
  • 淘宝做关键词的网站网站推广与优化平台
  • 广西茶叶网站建设seo点击
  • 一些好玩的网站网站搭建平台都有哪些
  • 做网站明细范文东营seo网站推广
  • wordpress注册上面的logo长沙百度快速优化
  • 新网站提交百度收录大连网络推广
  • 网站建设教程网站建设方案推广
  • b2c电子商务网站开发关键词生成器 在线
  • 营销型网站建设团队发布信息的免费平台
  • 重庆潼南网站建设公司百度竞价什么时候开始的
  • 购物网站建设的选题意义成都达洱狐网络科技有限公司
  • 全国建筑网站网页自助建站
  • 怎么把园林设计网站做的酷炫网络整合营销是什么意思
  • 网站建设etw推广网站要注意什么
  • 博客网页制作代码站外seo推广
  • 网络环境搭建网站优化seo培
  • 聊城做网站的公司流程百度代理公司怎么样
  • 网站分页怎么做谷歌搜索官网
  • 北京电商购物网站太原做网站哪家好
  • 做商城类网站备案时需提供什么证件淘宝代运营
  • 网站建设公司 电话销售没什么效果站长工具 站长之家
  • 广州市网站开发厦门seo优化推广
  • b2b网站建设模块推广网页
  • 工信部网站备案平台班级优化大师下载
  • wordpress 说说功能关键词的优化方案
  • 做网站建设销售工资高吗如何把自己的网站推广出去
  • 网站开发维护合同模板电子版郑州网站推广电话
  • 一家做特卖的网站手机版网络营销的方式包括