当前位置: 首页 > 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" />
http://www.lryc.cn/news/471002.html

相关文章:

  • 算法的学习笔记—左旋转字符串(牛客JZ58)
  • Mac 上无法烧录 ESP32C3 的问题记录:A fatal error occurred:Failed to write to target RAM
  • ios 项目升级极光SDK
  • 【Java】java | logback日志配置 | 按包配置级别
  • Virtuoso使用layout绘制版图、使用Calibre验证DRC和LVS
  • Spring框架原理面试题及参考答案
  • Java类的static成员以及代码块(详细版)
  • Opensearch集群部署【docker、服务器、Helm多种部署方式】
  • 本地Docker部署开源WAF雷池并实现异地远程登录管理界面
  • 性能需求笔记
  • ts:数组的常用方法(reduce累加)
  • Begin
  • 【实战案例】Django框架表单处理及数据库交互
  • python开发工具是选择vscode还是pycharm?两款软件优缺点对照!
  • 2025选题|基于Hadoop的物品租赁系统的设计与实现
  • 【Qt】QTableView添加下拉框过滤条件
  • 部署DNS主从服务器
  • 从可逆计算看低代码
  • 设计模式最佳实践代码总结 - 结构型设计模式篇 - 侨接设计模式最佳实践
  • 【软件测试】python——Unittest
  • Maven:详解 clean 和 install 命令的使用
  • HTTP与RPC
  • 解决蓝牙键盘按键错乱的问题
  • MiL.k X Biggie 奇妙宇宙来袭!
  • 云服务器中删除非空目录(包含文件和子目录)rm -rf <directory_name>
  • 1991-2024年经管类国自然、国社科立项名单(附68份国自然标书)-最新出炉 附下载链接
  • Flutter问题记录 - 布局中莫名其妙的白线/缝隙
  • 从零学习大模型(七)-----LoRA(中)
  • Java知识巩固(十二)
  • 一家光伏企业终止,恐不具行业代表性,市占率仅为2.35%