Android NSD局域网发现服务
近期在了解局域网发现服务的时候无意间看到Android 自带的(Network Service Discovery)网络发现服务,在一番验证之后发现实现比较简单,可靠性也高,因此在这里做一个整理,算是对自己知识做一个归档。
网络服务发现(NSD)是一种机制,它允许设备在本地网络上相互发现并提供服务。在Android平台上,NSD API使得应用可以轻松地发现和注册网络上的服务。以下是NSD的一些关键点和如何在Android应用中使用它:
1.NSD的基本概念: NSD实现了基于DNS的服务发现(DNS-SD)机制,允许应用通过指定服务类型和名称来请求服务。这使得用户可以发现并连接到其他设备上运行的相同应用,适用于文件共享、多人游戏等点对点应用。
2.注册服务: 在本地网络上注册服务是可选的。如果需要注册服务,首先需要创建一个NsdServiceInfo对象,该对象提供了其他设备在决定是否连接到您的服务时所需的信息。服务名称是实例名称,对网络上的其他设备可见,且必须是唯一的。服务类型指定了应用使用的协议和传输层,例如_http._tcp表示通过TCP运行的HTTP协议,关于协议列表可以在该网页中查到: Service Name and Transport Protocol Port Number Registry 。
3.发现服务: 要发现网络上的服务,需要设置一个发现监听器,并调用discoverServices()方法。监听器会通知应用何时启动、何时发生故障,以及何时发现和丢失服务。
4.权限要求: 使用NSD服务需要在应用的AndroidManifest.xml文件中添加网络权限,如INTERNET权限。
5.示例代码: 代码中有完整的注释,这里就不再过多赘述。
注册服务的示例代码
public class NsdService implements NsdManager.RegistrationListener {private final NsdManager mNsdManager;/*** 自定义服务名称,该名称对局域网内使用NSD查找本地服务的设备可见。* 名称必须唯一,但是如果网络中有同名的服务,安卓系统会自动处理冲突,其中一个会被自动转换为类似MyService(1)这样的名称。*/private String mServiceName = "MyService";/*** 服务类型,即指定应用使用的协议和传输层。* 语法是“_< protocol >._< transportlayer >”,这里服务使用了TCP协议上的HTTP协议。* 想要提供打印服务(例如,一台网络打印机)的应用应该将服务的类型设置为“_ipp._tcp”。* 其他协议可以IANA中查看到:https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml*/private String mServiceType = "_http._tcp.";NsdService(Context context) {mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);}/*** 注册服务* @param port 网络服务的端口*/public void registerService(int port) {//创建了一个NsdServiceInfo 并传入端口、服务名称和协议NsdServiceInfo serviceInfo = new NsdServiceInfo();//这里是你要告诉发现端,你的网络服务的端口,可能是你的server socket的启动端口,切记非NSD的启动端口。serviceInfo.setPort(port);serviceInfo.setServiceName(mServiceName);serviceInfo.setServiceType(mServiceType);//注册NAS服务,此处最后一个参数是NsdManager.RegistrationListener监听mNsdManager.registerService(serviceInfo,NsdManager.PROTOCOL_DNS_SD,this);}@Overridepublic void onServiceRegistered(NsdServiceInfo NsdServiceInfo) {Log.d("NSD", "Service registered: " + NsdServiceInfo.getServiceName());}@Overridepublic void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {Log.e("NSD", "Registration failed: Error code: " + errorCode);}@Overridepublic void onServiceUnregistered(NsdServiceInfo arg0) {Log.d("NSD", "Service unregistered");}@Overridepublic void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {Log.e("NSD", "Unregistration failed: Error code: " + errorCode);}
}
发现服务的示例代码
public class NsdDiscovery implements NsdManager.DiscoveryListener {private final NsdManager mNsdManager;/*** 服务类型,即指定应用使用的协议和传输层。* 语法是“_< protocol >._< transportlayer >”,这里服务使用了TCP协议上的HTTP协议。* 想要提供打印服务(例如,一台网络打印机)的应用应该将服务的类型设置为“_ipp._tcp”。* 其他协议可以IANA中查看到:https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml*/private String mServiceType = "_http._tcp.";NsdDiscovery(Context context) {mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);}//发现服务public void discoverServices() {//发现服务需要添加DiscoveryListener监听,关于发现服务所有的信息会在该回调内通知mNsdManager.discoverServices(mServiceType,NsdManager.PROTOCOL_DNS_SD,this);}@Overridepublic void onStartDiscoveryFailed(String serviceType, int errorCode) {Log.e("NSD", "Discovery start failed: Error code: " + errorCode);}@Overridepublic void onStopDiscoveryFailed(String serviceType, int errorCode) {Log.e("NSD", "Discovery stop failed: Error code: " + errorCode);}@Overridepublic void onDiscoveryStarted(String serviceType) {Log.d("NSD", "Service discovery started");}@Overridepublic void onDiscoveryStopped(String serviceType) {Log.d("NSD", "Discovery stopped: " + serviceType);}/*** 网络内发现了服务* @param serviceInfo*/@Overridepublic void onServiceFound(NsdServiceInfo serviceInfo) {Log.d("NSD", "Service discovery success " + serviceInfo);//检查服务的类型,确认这个类型我们的应用是否可以接入。if (!serviceInfo.getServiceType().equals(mServiceType)) {Log.d("NSD", "Unknown Service Type: " + serviceInfo.getServiceType());}//比较找到服务的名称与本地服务的名称,判断设备是否获得自己的(合法的)广播。else if (serviceInfo.getServiceName().contains("MyService")) {//如果是自己的服务,需要再进一步解析服务端的信息,包括IP和端口。mNsdManager.resolveService(serviceInfo, new ResolveListener());}}@Overridepublic void onServiceLost(NsdServiceInfo serviceInfo) {Log.e("NSD", "service lost" + serviceInfo);}private class ResolveListener implements NsdManager.ResolveListener {@Overridepublic void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {Log.e("NSD", "Resolve failed" + errorCode);}//解析完成之后通知@Overridepublic void onServiceResolved(NsdServiceInfo serviceInfo) {Log.d("NSD", "Resolve Succeeded. " + serviceInfo);// 连接到服务端的代码//...}}
}
不要忘记添加权限
<uses-permission android:name="android.permission.INTERNET" />
相关文章:
Android NSD局域网发现服务
近期在了解局域网发现服务的时候无意间看到Android 自带的(Network Service Discovery)网络发现服务,在一番验证之后发现实现比较简单,可靠性也高,因此在这里做一个整理,算是对自己知识做一个归档。 网络服…...
算法的学习笔记—左旋转字符串(牛客JZ58)
😀前言 在程序设计中,字符串处理问题屡见不鲜,其中“字符串左旋”是一种常见操作,今天我们一起来探讨一个经典的左旋转字符串题目,以及一种优雅的解决方案——三步翻转法。 🏠个人主页:尘觉主页…...
Mac 上无法烧录 ESP32C3 的问题记录:A fatal error occurred:Failed to write to target RAM
文章目录 问题描述驱动下载地址问题解决:安装 CH343 驱动踩的坑日志是乱码 问题描述 我代码编译可以,但是就是烧录不上去 A fatal error occurred:Failed to write to target RAM(result was 01070000:Operation timed out) Uploaderror:上传失败&…...
ios 项目升级极光SDK
由于项目使用的是旧版本,隐私合规检查不通过,需要升级到最新版本, 使用cocoapods集成无法正常运行,.a文件找不到,可能项目比较久了,最好选择手动导入 下载最新版本SDK,将 SDK 包解压ÿ…...
【Java】java | logback日志配置 | 按包配置级别
一、概述 日志配置需求: 本地部分包开debug,其他路径走配置;只在本地环境有效 二、logback.xml配置 <!--本地调试,开debug--> <springProfile name"dev"><logger name"cn.hg.demo" level&quo…...
Virtuoso使用layout绘制版图、使用Calibre验证DRC和LVS
1 绘制版图 1.1 进入Layout XL 绘制好Schmatic后,在原理图界面点击Launch,点击Layout XL进入版图绘制界面。 1.2 导入元件 1、在Layout XL界面左下角找打Generate All from Source。 2、在Generate Layout界面,选中“Instance”&#…...
Spring框架原理面试题及参考答案
目录 什么是Spring 开发框架? 说说Spring 的 IOC 和 DI? 简述IoC(控制反转)及在 Spring 中的实现 说说Spring IOC 容器的基本概念? 说说Spring IoC 的实现机制? 说说Spring IoC 容器? 简述Spring ApplicationContext 说说Spring Bean 的生命周期 说说在 Spring…...
Java类的static成员以及代码块(详细版)
文章目录 一、什么是static成员二、static修饰的成员有何意义三、static修饰成员变量四、static修饰成员方法4.1、静态成员变量不可以在方法内创建4.2、静态成员方法内部不可以访问非静态成员变量4.3、总结 五、static成员变量的初始化5.1、就地初始化5.2、静态代码块初始化 六…...
Opensearch集群部署【docker、服务器、Helm多种部署方式】
操作系统兼容性 我们建议在 Red Hat Enterprise Linux (RHEL) 或使用systemd的基于 Debian 的 Linux 发行版上安装 OpenSearch ,例如 CentOS、Amazon Linux 2 和 Ubuntu Long-Term Support (LTS)。OpenSearch 应该适用于大多数 Linux 发行版,但我们只测…...
本地Docker部署开源WAF雷池并实现异地远程登录管理界面
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
性能需求笔记
名称解释 系统用户:所有注册过的用户;在线用户:某时间段内登录且在线的用户 pv:用户浏览页面的次数 UV:登录系统的用户,uv课产生多个pv 性能测试:测试软件在系统中的运行性能,度量系…...
ts:数组的常用方法(reduce累加)
ts:数组的常用方法(reduce累加) 一、主要内容说明二、例子reduce方法(累加)1.源码1 (reduce方法)2.源码1运行效果 三、结语四、定位日期 一、主要内容说明 ts中数组的reduce方法,用…...
Begin
cpp 编程的发展方向还是很多的:游戏、嵌入式、QT、客户端、服务端、机器学习、算法大模 型 ...,现阶段还是不太清楚具体想走什么方向。主QT编程应该是不在考虑之内的,可以为辅简单 学习一下;游戏方向:需要学习lua语言…...
【实战案例】Django框架表单处理及数据库交互
本文基于之前内容列表如下: 【图文指引】5分钟搭建Django轻量级框架服务 【实战案例】Django框架基础之上编写第一个Django应用之基本请求和响应 【实战案例】Django框架连接并操作数据库MySQL相关API 【实战案例】Django框架使用模板渲染视图页面及异常处理 更新编…...
python开发工具是选择vscode还是pycharm?两款软件优缺点对照!
Pycharm和VSCode是两款流行的代码编辑器,它们都有各自的优缺点和适用情况。本文将从以下几个方面对它们进行比较和分析: 功能和扩展性性能和稳定性用户体验和界面价格和支持 功能和扩展性 Pycharm是一款专为Python开发而设计的集成开发环境(…...
2025选题|基于Hadoop的物品租赁系统的设计与实现
作者简介:Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验,被多个学校常年聘为校外企业导师,指导学生毕业设计并参与学生毕业答辩指导,…...
【Qt】QTableView添加下拉框过滤条件
实现通过带复选框的下拉框来为表格添加过滤条件 带复选框的下拉框 .h文件 #pragma once #include <QCheckBox> #include <QComboBox> #include <QEvent> #include <QLineEdit> #include <QListWidget>class TableComboBox : public QComboBox …...
部署DNS主从服务器
一。DNS主从服务器作用: DNS作为重要的互联网基础设施服务,保证DNS域名解析服务的正常运转至关重要,只有这样才能提供稳定、快速日不间断的域名查询服务 DNS 域名解析服务中,从服务器可以从主服务器上获取指定的区域数据文件&…...
从可逆计算看低代码
2020年低代码(LowCode)这一buzzword频繁亮相于主流技术媒体,大背景下是微软/亚马逊/阿里/华为等巨头纷纷入场,推出自己的相应产品。一时之间,大大小小的技术山头,无论自己原先是搞OA/ERP/IOT/AI的ÿ…...
设计模式最佳实践代码总结 - 结构型设计模式篇 - 侨接设计模式最佳实践
目录 侨接设计模式最佳实践 侨接设计模式最佳实践 桥接模式是一种结构型设计模式,它将抽象部分与它的实现部分分离,使它们可以独立地变化。桥接模式是一种结构型设计模式,它将抽象部分与它的实现部分分离,使它们可以独立地变化。…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
