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

文章目录

  • 需求
  • 实现方法
    • 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.xdnf.cn/news/147476.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL内存(Buffer Pool)

Buffer Pool MySQL 的数据存在磁盘&#xff0c;但是不能每次读取数据都从磁盘里去&#xff0c;这样磁盘IO太频繁&#xff0c;存在性能问题。 InnoDB设计了一个缓存池&#xff08;Buffer Pool&#xff09;&#xff0c;缓冲池在内存中。 默认配置Buffer Pool大小为128MB&#xf…

Trapezoidal Decomposition梯形分解算法(TCD)

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言Trapezoidal Decomposition梯形分解算法&#xff08;TCD&#xff09;原理&#xff08;1&#xff09;第一种原理&#xff08;2…

DataX实战:从MongoDB到MySQL的数据迁移--修改源码并测试打包

在现代数据驱动的业务环境中&#xff0c;数据迁移和集成是常见的需求。DataX&#xff0c;作为阿里云开源的数据集成工具&#xff0c;提供了强大的数据同步能力&#xff0c;支持多种数据源和目标端。本文将介绍如何使用DataX将数据从MongoDB迁移到MySQL。 环境准备 安装MongoDB…

智慧医院人工智能应用场景 | 智能导诊系统源码

近年来&#xff0c;智能医疗在国内外的发展热度不断提升。图像识别、深度学习、神经网络、大模型、语音等关键技术的突破带来了人工智能技术新一轮的发展。 场景一&#xff1a;智能机器人 医疗机器人是指能够在医疗领域执行特定任务或功能的机器人&#xff0c;包括手术机器人、…

【LLaMa2入门】从零开始训练LLaMa2

目录 1 背景2 搭建环境2.1 硬件配置2.2 搭建虚拟环境2.2.1 创建虚拟环境2.2.2 安装所需的库 3 准备工作3.1 下载GitHub代码3.2 下载模型3.3 数据处理3.3.1 下载数据3.3.2 数据集tokenize预处理 4 训练4.1 修改配置4.2 开始训练4.3 多机多卡训练 5 模型推理5.1 编译5.1.1 安装gc…

Java算法专栏

专栏导读 在当今这个技术日新月异的时代&#xff0c;Java算法作为软件开发的核心&#xff0c;对于提升程序性能和解决复杂问题至关重要。本“Java算法”专栏旨在帮助读者深入理解Java编程语言中的算法原理和应用&#xff0c;通过实战案例和深入分析&#xff0c;使读者能够掌握…

软媒市场新探索:软文媒体自助发布,开启自助发稿新篇章

在繁华喧嚣的软媒市场中,每一个声音都在竭力呼喊,每一个品牌都在奋力展现。而软文,作为一种温柔而坚韧的营销力量,正逐渐崭露头角。特别是软文媒体自助发布平台的出现,更是为企业提供了一个全新的、高效的自助发稿渠道。 软媒市场自助发布平台,正如其名,是一个让企业能够自主发…

【LeetCode】每日一题 2024_9_21 边积分最高的节点(哈希)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;边积分最高的节点 代码与解题思路 func edgeScore(edges []int) (ans int) {// 直接维护哈希最大值即可mp : map[int]int{}for i, v : range edges {mp[v] i// 如果多个节点的 边积分 相…

【数据库】常用数据库简介

目录 &#x1f354; 常用的关系型数据库 &#x1f354; Mysql简介 &#x1f354; SQL 简介 SQL语句的分类 SQL 写法 SQL 常用的数据类型 &#x1f354; DDL语句 对数据库的操作 对数据表的操作 &#x1f354; DML语句 插入数据 insert into 修改数据 update 删除数…

Ubuntu下使用 python搭建服务实现从web端远程配置设备网口

1、通过文件配置Ubuntu设备网口 在Ubuntu工控机上&#xff0c;通过文件配置网口&#xff08;网络接口&#xff09;可以让网络配置在每次系统启动时自动生效。以下是常见的方法步骤&#xff1a; 1.1 使用 netplan 配置网口&#xff08;Ubuntu 18.04 及以上版本&#xff09; 编…

探索微软Copilot Agents:如何通过Wave 2 AI彻底改变工作方式

微软在最近的Copilot Wave 2发布会上&#xff0c;展示了一系列将彻底改变日常工作流程的新AI功能&#xff0c;尤其是 Copilot Agents&#xff0c;它们不仅仅是简单的工具&#xff0c;而是真正的工作助理&#xff0c;可以自动完成任务、提供智能分析并帮助你做出决策。这些新功能…

Day6:反转链表

题目&#xff1a;给你单链表的头节点head&#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 输入&#xff1a;head[1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] public ListNode reverseList() {if (head null) {return head;}ListNode cur head.next;head.next null…

Python脚本每日自动备份MySQL数据库,无需mysqldump

编写一个Python脚本&#xff0c;每天凌晨3点开始备份 脚本具有以下特点 不需要安装mysql-client&#xff0c;并且Windows Linux都可以使用支持多个数据库连接的备份每个数据库支持多个表备份日志保存下来&#xff0c;方便第二天早上查看备份结果 首先安装需要的库 pip3 ins…

调节 PWM的占空比控制舵机的角度

一、PWM工作原理 让计数器从0数到自动重装载值&#xff0c;不停计数。计数值小于输出比较寄存器时输出一种电平&#xff0c;大于输出比较寄存器时使出另一种电平。 修改定时器时钟源的速度以及预分频器等设置&#xff0c;可以修改计数器计数的速度 再加上修改自动重装载值&…

肺结节检测系统源码分享

肺结节检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Visio…

python画图|图像背景颜色设置

python画图出来的默认图形背景是白色&#xff0c;有时候并不适合大家表达想要表达的意思。 因此&#xff0c;我们很有必要掌握自己设置图形背景颜色的技巧。 【1】官网教程 首先请各位看官移步官网&#xff0c;看看官网如何设置&#xff0c;下述链接可轻松到达&#xff1a; …

如何将很多个pdf拼接在一起?很多种PDF拼接的方法

如何将很多个pdf拼接在一起&#xff1f;将多个PDF文件合并不仅能够提升信息的整合性&#xff0c;还能使文件管理更加高效。想象一下&#xff0c;你需要向同事或老师提交一份综合报告&#xff0c;其中包含了多份相关资料。如果每个文件单独存在&#xff0c;查找和传输都会变得繁…

IDEA中Quarkus框架(3.13版本)开发、调试、部署、打包等

code-with-quarkus code-with-quarkus 是使用官网生成的demo项目 这个项目使用Quarkus&#xff08;使用3.13.0版本&#xff0c;该版本支持JDK21&#xff09;&#xff0c;超音速亚原子Java框架。官网地址: https://quarkus.io/. 环境要求 OS: Windows 10.0 jdk 11 maven 3.9…

2024年研赛-华为杯数模竞赛F题论文首发+论文讲解

本届研赛助攻题目 C D F三题论文均已经全部完成。后更新计划 如图所示。 免费给大家分享 三个问题的论文部分代码 2024年华为杯-研赛分享资料&#xff08;论文部分代码&#xff09;&#xff08;已更新部分代码&#xff09;&#xff1a; 链接&#xff1a;https://pan.baidu.com…

【Pyside】pycharm2024配置conda虚拟环境

知识拓展 Pycharm 是一个由 JetBrains 开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它主要用于 Python 编程语言的开发。Pycharm 提供了代码编辑、调试、版本控制、测试等多种功能&#xff0c;以提高 Python 开发者的效率。 Pycharm 与 Python 的关系 Pycharm 是…