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

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 自带的&#xff08;Network Service Discovery&#xff09;网络发现服务&#xff0c;在一番验证之后发现实现比较简单&#xff0c;可靠性也高&#xff0c;因此在这里做一个整理&#xff0c;算是对自己知识做一个归档。 网络服…...

算法的学习笔记—左旋转字符串(牛客JZ58)

&#x1f600;前言 在程序设计中&#xff0c;字符串处理问题屡见不鲜&#xff0c;其中“字符串左旋”是一种常见操作&#xff0c;今天我们一起来探讨一个经典的左旋转字符串题目&#xff0c;以及一种优雅的解决方案——三步翻转法。 &#x1f3e0;个人主页&#xff1a;尘觉主页…...

Mac 上无法烧录 ESP32C3 的问题记录:A fatal error occurred:Failed to write to target RAM

文章目录 问题描述驱动下载地址问题解决&#xff1a;安装 CH343 驱动踩的坑日志是乱码 问题描述 我代码编译可以&#xff0c;但是就是烧录不上去 A fatal error occurred:Failed to write to target RAM(result was 01070000:Operation timed out) Uploaderror:上传失败&…...

ios 项目升级极光SDK

由于项目使用的是旧版本&#xff0c;隐私合规检查不通过&#xff0c;需要升级到最新版本&#xff0c; 使用cocoapods集成无法正常运行&#xff0c;.a文件找不到&#xff0c;可能项目比较久了&#xff0c;最好选择手动导入 下载最新版本SDK&#xff0c;将 SDK 包解压&#xff…...

【Java】java | logback日志配置 | 按包配置级别

一、概述 日志配置需求&#xff1a; 本地部分包开debug&#xff0c;其他路径走配置&#xff1b;只在本地环境有效 二、logback.xml配置 <!--本地调试&#xff0c;开debug--> <springProfile name"dev"><logger name"cn.hg.demo" level&quo…...

Virtuoso使用layout绘制版图、使用Calibre验证DRC和LVS

1 绘制版图 1.1 进入Layout XL 绘制好Schmatic后&#xff0c;在原理图界面点击Launch&#xff0c;点击Layout XL进入版图绘制界面。 1.2 导入元件 1、在Layout XL界面左下角找打Generate All from Source。 2、在Generate Layout界面&#xff0c;选中“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 &#xff0c;例如 CentOS、Amazon Linux 2 和 Ubuntu Long-Term Support (LTS)。OpenSearch 应该适用于大多数 Linux 发行版&#xff0c;但我们只测…...

本地Docker部署开源WAF雷池并实现异地远程登录管理界面

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

性能需求笔记

名称解释 系统用户&#xff1a;所有注册过的用户&#xff1b;在线用户&#xff1a;某时间段内登录且在线的用户 pv&#xff1a;用户浏览页面的次数 UV&#xff1a;登录系统的用户&#xff0c;uv课产生多个pv 性能测试&#xff1a;测试软件在系统中的运行性能&#xff0c;度量系…...

ts:数组的常用方法(reduce累加)

ts&#xff1a;数组的常用方法&#xff08;reduce累加&#xff09; 一、主要内容说明二、例子reduce方法&#xff08;累加&#xff09;1.源码1 &#xff08;reduce方法&#xff09;2.源码1运行效果 三、结语四、定位日期 一、主要内容说明 ts中数组的reduce方法&#xff0c;用…...

Begin

cpp 编程的发展方向还是很多的&#xff1a;游戏、嵌入式、QT、客户端、服务端、机器学习、算法大模 型 ...&#xff0c;现阶段还是不太清楚具体想走什么方向。主QT编程应该是不在考虑之内的&#xff0c;可以为辅简单 学习一下&#xff1b;游戏方向&#xff1a;需要学习lua语言…...

【实战案例】Django框架表单处理及数据库交互

本文基于之前内容列表如下&#xff1a; 【图文指引】5分钟搭建Django轻量级框架服务 【实战案例】Django框架基础之上编写第一个Django应用之基本请求和响应 【实战案例】Django框架连接并操作数据库MySQL相关API 【实战案例】Django框架使用模板渲染视图页面及异常处理 更新编…...

python开发工具是选择vscode还是pycharm?两款软件优缺点对照!

Pycharm和VSCode是两款流行的代码编辑器&#xff0c;它们都有各自的优缺点和适用情况。本文将从以下几个方面对它们进行比较和分析&#xff1a; 功能和扩展性性能和稳定性用户体验和界面价格和支持 功能和扩展性 Pycharm是一款专为Python开发而设计的集成开发环境&#xff08;…...

2025选题|基于Hadoop的物品租赁系统的设计与实现

作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参与学生毕业答辩指导&#xff0c;…...

【Qt】QTableView添加下拉框过滤条件

实现通过带复选框的下拉框来为表格添加过滤条件 带复选框的下拉框 .h文件 #pragma once #include <QCheckBox> #include <QComboBox> #include <QEvent> #include <QLineEdit> #include <QListWidget>class TableComboBox : public QComboBox …...

部署DNS主从服务器

一。DNS主从服务器作用&#xff1a; DNS作为重要的互联网基础设施服务&#xff0c;保证DNS域名解析服务的正常运转至关重要&#xff0c;只有这样才能提供稳定、快速日不间断的域名查询服务 DNS 域名解析服务中&#xff0c;从服务器可以从主服务器上获取指定的区域数据文件&…...

从可逆计算看低代码

2020年低代码&#xff08;LowCode&#xff09;这一buzzword频繁亮相于主流技术媒体&#xff0c;大背景下是微软/亚马逊/阿里/华为等巨头纷纷入场&#xff0c;推出自己的相应产品。一时之间&#xff0c;大大小小的技术山头&#xff0c;无论自己原先是搞OA/ERP/IOT/AI的&#xff…...

设计模式最佳实践代码总结 - 结构型设计模式篇 - 侨接设计模式最佳实践

目录 侨接设计模式最佳实践 侨接设计模式最佳实践 桥接模式是一种结构型设计模式&#xff0c;它将抽象部分与它的实现部分分离&#xff0c;使它们可以独立地变化。桥接模式是一种结构型设计模式&#xff0c;它将抽象部分与它的实现部分分离&#xff0c;使它们可以独立地变化。…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...