局域网设备自动发现常用方法

文章目录

  • 需求
  • 实现方法
    • ARP (Address Resolution Protocol)
      • Ping ip的流程
      • 抓包如下
      • 代码实现
    • mDNS
  • 对比测试
    • Avahi 介绍
    • Avahi 安装
    • Avahi 使用
    • 测试代码

需求

局域网设备自动发现是软件开发中的一个常见且重要的需求,它简化了设备间的协作机制,降低了软件各模块间进行复杂配置的需求。通过实现自动发现功能,不仅显著提升了用户的操作便捷性和满意度,还促进了网络资源的智能化分配与高效利用。为后续的通信和传输奠定了基础。

局域网设备自动发现通常具有以下几个核心功能:

  • 实时性:能够即时探测到局域网中新加入或离开的设备,确保网络环境的实时更新。
  • 广泛性:支持多种类型的设备发现,包括但不限于计算机、打印机、智能家电、网络摄像头等。
  • 易用性:用户无需手动配置或输入设备的IP地址等信息,即可轻松访问和使用这些设备。
  • 安全性:在自动发现设备的同时,也考虑到了网络安全问题,如防止未授权设备的接入等。

实现方法

ARP (Address Resolution Protocol)

ARP是一种协议,用于将 IP地址解析成 MAC 地址。当主机想要与同一局域网内的另一台主机通信时,它需要知道目标主机的 MAC 地址。ARP 就是用来完成这一任务的协议。ARP 请求是通过广播方式进行的,所有接收到 ARP 请求的设备都会检查是否请求的是自己的 IP 地址,如果是,则响应自己的 MAC 地址。

Ping ip的流程

当你使用 Ping 向某个 IP 地址发送数据包时,首先需要知道该 IP 地址对应的 MAC 地址。这就是 ARP 的作用

一台计算机 A 要 Ping 另一台计算机 B,过程如下:

  • A 查询自己的 ARP 缓存表,看是否有 B 的 IP 地址对应的 MAC 地址记录。
  • 如果找不到,则 A 发送一个 ARP 请求到局域网内所有设备(广播),询问谁拥有 B 的 IP 地址。
  • B 接收到 ARP 请求后,如果匹配自己的 IP 地址,就回复 ARP 响应给 A,告诉它自己的 MAC 地址。
  • A 收到 ARP 响应后,记录下 B 的 MAC 地址,并更新 ARP 缓存表。
  • A 然后构造一个 ICMP Echo Request 数据包,并使用 B 的 MAC 地址发送给 B。
  • B 收到 ICMP Echo Request 后,回应一个 ICMP Echo Reply 给 A。
  • A 收到回声应答,表示连通性测试成功。

抓包如下

在这里插入图片描述

代码实现

下面是简单c语言示例,
使用原始套接字发送 ARP 请求并接收 ARP 响应来获取局域网内所有在线设备的 IP 地址

安装 npm install libpcap-dev

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/arp.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <ifaddrs.h>#define BROADCAST_MAC "\xff\xff\xff\xff\xff\xff"void send_arp_request(int sockfd, struct ether_header *eh, struct arphdr *arp, char *mac, char *ip, char *target_ip) {memset(arp, 0, sizeof(struct arphdr));arp->ar_hrd = htons(ARPHRD_ETHER);    /* Ethernet */arp->ar_pro = htons(ETH_P_IP);       /* IP Protocol */arp->ar_op  = htons(AROP_REQUEST);   /* ARP Request */memcpy(arp->ar_saddr, mac, ETH_ALEN); /* Sender hardware address */memcpy(arp->ar_sha, mac, ETH_ALEN);  /* Sender hardware address */memcpy(arp->ar_tpa, inet_aton(target_ip), 4); /* Target protocol address */memcpy(arp->ar_tha, "\x00\x00\x00\x00\x00\x00", 6); /* Target hardware address (all zeros) */memcpy(arp->ar_spa, inet_aton(ip), 4); /* Sender protocol address */eh->ether_dhost[0] = BROADCAST_MAC[0]; /* Destination MAC address (Broadcast) */eh->ether_dhost[1] = BROADCAST_MAC[1];eh->ether_dhost[2] = BROADCAST_MAC[2];eh->ether_dhost[3] = BROADCAST_MAC[3];eh->ether_dhost[4] = BROADCAST_MAC[4];eh->ether_dhost[5] = BROADCAST_MAC[5];eh->ether_type = htons(ETHER_TYPE_ARP); /* ARP Packet */sendto(sockfd, eh, sizeof(struct ether_header) + sizeof(struct arphdr), 0, NULL, 0);
}int main(void) {struct ifaddrs *ifAddrStruct = NULL;struct ifaddrs *tmpAddrPtr = NULL;int sockfd;char *target_ip = "192.168.1.0"; /* 目标 IP 地址段 */int i = 0;int len = 0;/* 获取本地接口信息 */if (getifaddrs(&ifAddrStruct) == -1) {perror("getifaddrs");return -1;}/* 打开原始套接字 */if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {perror("socket");freeifaddrs(ifAddrStruct);return -1;}tmpAddrPtr = ifAddrStruct;while (tmpAddrPtr != NULL) {if (tmpAddrPtr->ifa_addr != NULL && strcmp(tmpAddrPtr->ifa_name, "lo") != 0) {char *ip = inet_ntoa(*(struct in_addr *)tmpAddrPtr->ifa_addr);struct ether_header eh;struct arphdr arp;send_arp_request(sockfd, &eh, &arp, (char *)tmpAddrPtr->ifa_ifu.ifu_data, ip, target_ip);/* 循环发送 ARP 请求 */for (i = 1; i <= 254; i++) {char ipaddr[INET_ADDRSTRLEN];sprintf(ipaddr, "%s.%d", target_ip, i);send_arp_request(sockfd, &eh, &arp, (char *)tmpAddrPtr->ifa_ifu.ifu_data, ip, ipaddr);}}tmpAddrPtr = tmpAddrPtr->ifa_next;}/* 清理 */freeifaddrs(ifAddrStruct);close(sockfd);return 0;
}

mDNS

  • mDNS(Multicast DNS)协议:使用5353端口,组播地址 224.0.0.251。

在一个没有常规DNS服务器的小型网络内,可以使用mDNS来实现类似DNS的编程接口、包格式和操作语义。MDNS协议的报文与DNS的报文结构相同,但有些字段对于MDNS来说有新的含义。

在局域网中,设备和设备之前相互通信需要知道对方的ip地址的,大多数情况,设备的ip不是静态ip地址,而是通过dhcp 协议动态分配的ip 地址,mDNS如何设备发现呢,

  • UPnP(Universal Plug and Play)技术:UPnP技术旨在让智能设备能够自动发现网络上的其他UPnP设备,并与之进行通信和协作。它支持设备之间的动态服务发现、自动配置和事件通知等功能。
  • LLMNR(Link-Local Multicast Name Resolution)协议:作为DNS的一种补充,LLMNR协议在局域网内通过多播方式解析设备的名称和地址。它特别适用于IPv6网络环境,并能够在DNS服务不可用的情况下提供快速的名称解析服务。
  • SNMP(Simple Network Management Protocol)协议:虽然SNMP主要用于网络管理而非设备发现,但它可以通过轮询网络中的设备来收集其状态信息,从而间接实现设备发现的目的。通过SNMP,管理员可以获取设备的型号、序列号、固件版本等详细信息。
  • 自定义协议

对比测试

Avahi 介绍

Avahi 是一个开源项目,提供了一套用于实现 mDNS (Multicast DNS) 和 SSDP (Simple Service
Discovery Protocol) 的工具和库。它主要用于局域网内的零配置网络服务发现。Avahi 支持多种操作系统,包括 Linux、BSD 变体以及其他类 Unix 系统。
Avahi 库的主要用途

  • 服务发现: 让设备在本地网络中自动发现彼此提供的服务。
  • 名称解析: 自动解析设备和服务的名称到 IP 地址,而无需手动配置。
  • 广告服务: 让设备能够发布自己提供的服务,以便其他设备可以发现。
  • 多播 DNS: 利用 mDNS 进行服务发现和名称解析。
  • 简单服务发现协议: 通过 SSDP 进行服务发现

Avahi 安装

yum install avahi libavahi-client-devel

在这里插入图片描述

Avahi 使用

常用API
初始化

avahi_init();

创建 Avahi 客户端:

AvahiClient *client;
client = avahi_client_new(avahi_poll_get(), AVAHI_CLIENT_FLAG_USE_MULTICAST, NULL, NULL);

回调监听状态变化

static void client_callback(AvahiClient *client, AvahiClientState state, void *userdata) {// 处理状态变化
}
avahi_client_set_callback(client, client_callback, NULL);

测试代码

#include <avahi-common/poll.h>
#include <avahi-core/core.h>
#include <avahi-client/client.h>
#include <stdio.h>
#include <stdlib.h>static void service_resolved(AvahiServiceResolvedEvent *event, void *userdata) {printf("Found service '%s' at '%s', port %d.\n",event->name, event->address, event->port);
}static void client_callback(AvahiClient *client, AvahiClientState state, void *userdata) {AvahiEntryGroup *group;AvahiEntryGroupState group_state;AvahiServiceResolver *res;if (state != AVAHI_CLIENT_S_RUNNING)return;/* Create a new entry group */if ((group = avahi_client_new_entry_group(client)) == NULL) {fprintf(stderr, "No memory, aborting.\n");return;}/* Setup callback for the entry group */avahi_entry_group_set_callback(group, entry_group_state_callback, userdata);/* Add a service browser to the entry group */if (avahi_entry_group_add_service_browser(group,AVAHI_IF_UNSPECIFIED,AVAHI_PROTO_INET,"_service._tcp", NULL, NULL) < 0) {fprintf(stderr, "Could not add service browser to entry group.\n");avahi_entry_group_free(group);return;}/* Commit the entry group */if (avahi_entry_group_commit(group) < 0) {fprintf(stderr, "Could not commit entry group.\n");avahi_entry_group_free(group);return;}/* Wait until the entry group is ready */do {avahi_entry_group_get_state(group, &group_state);} while (group_state != AVAHI_ENTRY_GROUP_COMMITTED);/* Now we can resolve services */if ((res = avahi_client_alloc_service_resolver(client)) == NULL) {fprintf(stderr, "No memory, aborting.\n");return;}avahi_service_resolver_set_callback(res, service_resolved, NULL);/* Resolve the first found service */avahi_service_resolver_resolve(res,AVAHI_IF_UNSPECIFIED,AVAHI_PROTO_INET,"my-service", "local", NULL);
}int main(int argc, char *argv[]) {AvahiClient *client;AvahiClientState initial_state;/* Initialize Avahi library */avahi_init();/* Create a new client object */if ((client = avahi_client_new(avahi_poll_get(), AVAHI_CLIENT_FLAG_USE_MULTICAST, client_callback, NULL)) == NULL) {fprintf(stderr, "Failed to create client.\n");return 1;}/* Get the initial client state */avahi_client_get_state(client, &initial_state);/* Main loop */while (initial_state != AVAHI_CLIENT_S_RUNNING) {avahi_client_wait(client, 1000);avahi_client_get_state(client, &initial_state);}/* Clean up */avahi_client_free(client);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/53529.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实验九 多线程的处理

实验目的及要求 目的&#xff1a;理解线程的概念&#xff0c;掌握Java的多线程机制&#xff0c;会用多线程编写Java程序。 要求&#xff1a; 理解线程的概念会用Thread类创建线程会使用Runnable接口创建多线程对两种实现多线程方式的方式进行对比掌握线程的同步 二、实验环境…

Pygame中Sprite类实现多帧动画3-3

4 使用自定义类MySprite 使用自定义类MySprite实现多帧动画的步骤是首先创建MySprite类的实例&#xff0c;之后使用相关函数对该实例进行操作。 4.1 创建MySprite类的实例 创建MySprite类的实例的代码如图12所示。 图12 创建MySprite类的实例的代码 其中&#xff0c;变量dr…

TortoiseGit无法安装解决方案

Win11安装TortoiseGit报错&#xff0c;错误码&#xff1a;2503&#xff0c;如下图&#xff1a; 开始-右键-Windows PowerShell&#xff08;管理员&#xff09;/终端 (管理员) 输入 msiexec /package 安装程序所在绝对路径&#xff0c; 例如 : msiexec /package D:\我的资料…

利用鸢尾花数据集介绍PCA算法

PCA&#xff1a; 主成分分析&#xff08;PCA, Principal Component Analysis&#xff09;是一种常用的数据降维技术&#xff0c;它可以将高维数据转换为较低维数据&#xff0c;同时尽可能保留数据的主要信息。PCA通过寻找数据的主要方向&#xff0c;即方差最大的方向&#xff0…

小小GCD、LCM拿下拿下

目录 最大公约数&#xff08;GCD&#xff09; 最大公约数&#xff08;GCD&#xff09;求解&#xff1a; 一、辗转相除法 二、三目运算符 三、位运算 最大公约数&#xff08;GCD&#xff09;模板&#xff1a; 最大公约数&#xff08;GCD&#xff09;例题&#xff1a; 最…

stm32之硬件SPI读写W25Q64存储器应用案例

系列文章目录 1. stm32之SPI通信协议 2. stm32之软件SPI读写W25Q64存储器应用案例 3. stm32之SPI通信外设 文章目录 系列文章目录前言一、电路接线图二、应用案例代码三、应用案例代码分析3.1 基本思路3.2 相关库函数介绍3.3 MySPI模块3.3.1 模块初始化3.3.2 SPI基本时序单元模…

丰巢“闯关”港交所上市

社区中随处可见的智能快递柜&#xff0c;即将捧出一个IPO。 近日&#xff0c;丰巢控股有限公司&#xff08;下称“丰巢控股”或“丰巢”&#xff09;正式向港交所递交了招股书&#xff0c;华泰国际担任其独家保荐人。这将是继顺丰控股、顺丰房托、嘉里物流、顺丰同城之后&…

微服务CI/CD实践(六)Jenkins Docker 自动化构建部署Java微服务

微服务CI/CD实践系列&#xff1a; 微服务CI/CD实践&#xff08;一&#xff09;环境准备及虚拟机创建 微服务CI/CD实践&#xff08;二&#xff09;服务器先决准备 微服务CI/CD实践&#xff08;三&#xff09;gitlab部署及nexus3部署 微服务CI/CD实践&#xff08;四&#xff09…

未来餐饮革命:加入我们的智能餐厅代理、自主开拓市场计划!

系统开发集成商&#xff1a;如果您正在开发智慧餐厅系统&#xff0c;忙于寻找各种消费终端接入、那么我们将可以为您提供整套智慧餐厅系统解决方案&#xff0c;从前厅消费到后厨的明厨亮灶的解决方案。 集团公司&#xff1a;想集团化控制子公司食堂运营&#xff0c;又想以最低…

【LeetCode每日一题】——LCR 168.丑数

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目注意】六【题目示例】七【题目提示】八【解题思路】九【时间频度】十【代码实现】十一【提交结果】 一【题目类别】 优先队列 二【题目难度】 中等 三【题目编号】 LCR 168.丑数 四【题目描述…

【大数据】Hadoop里的“MySQL”——Hive,干货满满

【大数据】Hadoop里的“MySQL”——Hive&#xff0c;干货满满 文章脉络 Hive架构 HQL 表类型 创建表语法 分区 数据导入导出 函数 内置函数 UDF Java Python 在阅读本文前&#xff0c;请确保已经对Hadoop的三大组件&#xff08;HDFS、MapReduce、YARN&#xff09;有…

分布式协调服务--ZooKeeper

文章目录 ZooKeeperzk的由来zk解决了什么问题 ZK工作原理ZK数据模型zk功能1.命名服务2.状态同步3.配置中心4.集群管理 zk部署单机启动zk验证zk zk集群集群角色选举过程1.节点角色状态2.选举ID3.具体过程4.心跳机制5.ZAB协议 ZooKeeper 选举示例1.第一轮投票&#xff1a;2.节点收…

Unity TextMeshPro 设置竖排

默认竖排是这样的 但是我们要的竖排效果并不是这样我们要是竖排连续的根据文本限制来进行换行 第一步我们先设置文本的旋转Z轴为90如下图 然后我们给文本加一个Tag <rotate270> 如下图 但是这个效果还是不是我们想要的效果我们可以使用TexeMeshPro提供的一个选项EnableR…

Python画笔案例-041 绘制正方形阶梯

1、绘制正方形阶梯 通过 python 的turtle 库绘制正方形阶梯&#xff0c;如下图&#xff1a; 2、实现代码 绘制正方形阶梯&#xff0c;以下为实现代码&#xff1a; """正方形阶梯.py """ import turtledef draw_square(length):for _ in range(6…

以太网--TCP/IP协议(一)

概述 以太网是局域网的一种&#xff0c;其他的比如还有令牌环、FDDI。和局域网对应的就是广域网&#xff0c;如Internet&#xff0c;城域网等。 从网络层次看&#xff0c;局域网协议主要偏重于低层&#xff08;业内一般把物理层、数据链路层归为低层&#xff09;。以太网协议…

Qt工程使用MQTT-C库与mqtt服务器数据通信

实现mqtt订阅与发布话题&#xff0c;与mqtt服务器进行数据通信 编译环境&#xff1a;Qt5.15.2 vs2019 需要mqttc库&#xff1a;mqttc.lib, mqttc.dll&#xff08;根据MQTT-C源码编译出来的库&#xff0c;参考cmake编译MQTT-C源码-CSDN博客&#xff09; 一、Qt pro文件编写 …

数据结构C //线性表ADT结构及相关函数

数据结构&#xff08;C语言版&#xff09;严蔚敏 吴伟民 线性表ADT结构及相关函数 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块&#xff08;头文件&#xff0c;函数文件&#xff0c;主文件&#xff09; list.h头文件 /****…

LeetCode 2181.合并零之间的节点

题目描述 给你一个链表的头节点 head &#xff0c;该链表包含由 0 分隔开的一连串整数。链表的 开端 和 末尾 的节点都满足 Node.val 0 。 对于每两个相邻的 0 &#xff0c;请你将它们之间的所有节点合并成一个节点&#xff0c;其值是所有已合并节点的值之和。然后将所有 0 …

浏览器百科:网页存储篇-如何在Chrome中打开IndexedDB窗格(十一)

1.引言 在现代Web开发中&#xff0c;网页存储技术扮演着至关重要的角色。IndexedDB作为一种低级API&#xff0c;允许客户端存储大量结构化数据&#xff0c;并提供高性能的搜索能力。在上一篇文章中&#xff0c;我们深入探讨了IndexedDB的基础知识及其应用场景。为了更有效地调…

安全产品概述

防火墙 防火墙的核心功能是过滤掉有害的流量&#xff0c;在专用网络和公共网络之间建立保护屏障。防火墙过滤通常基于一系列规则&#xff0c;如 IP 地址、域名、协议、端口号、关键字等&#xff0c;对入站和出站的流量进行过滤。这些规则也称为访问控制列表&#xff08;ACCESS…