Android网络服务发现(NSD)使用
NSD(NsdManager)是Android SDK中自带的类库,可以集成直接使用。
使用 NSD服务需要(android4.1及以上) minSdkVersion >16
通常应用于局域网内不同应用设备的互联.
Nsd的两个功能
- Nsd 注册功能:
进行Nsd注册:自定义服务名、端口号,IP地址注册到Nsd服务中 - Nsd 扫描功能:
扫描到当前局域网内所有已通过NSD注册了的应用设备的网络信息(服务名、端口号、IP地址)
Nsd服务端
步骤
- NsdManager初始化
nsdManager = (NsdManager) getSystemService(NSD_SERVICE);
- 创建一个server来获取端口
try {
mServerSocket = new ServerSocket(0);//设为0,会自动获取没有占用的端口
mPort = mServerSocket.getLocalPort();
} catch (IOException e) {
e.printStackTrace();
}
- 创建NsdServiceInfo
mNsdServiceInfo = new NsdServiceInfo();
mNsdServiceInfo.setServiceName(SERVICE_NAME);
mNsdServiceInfo.setServiceType(SERVICE_TYPE);
mNsdServiceInfo.setPort(mPort);
- 创建注册监听
private void createRegistration() {
mRegistrationListener = new NsdManager.RegistrationListener() {
@Override
public void onRegistrationFailed(NsdServiceInfo nsdServiceInfo, int i) {
Toast.makeText(MainActivity.this, "onRegistrationFailed", Toast.LENGTH_SHORT).show();
}
@Override
public void onUnregistrationFailed(NsdServiceInfo nsdServiceInfo, int i) {
Toast.makeText(MainActivity.this, "onUnregistrationFailed", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceRegistered(NsdServiceInfo nsdServiceInfo) {
Toast.makeText(MainActivity.this, "onServiceRegistered", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceUnregistered(NsdServiceInfo nsdServiceInfo) {
Toast.makeText(MainActivity.this, "onServiceUnregistered", Toast.LENGTH_SHORT).show();
}
};
}
- 注册
mNsdManager = (NsdManager) getSystemService(NSD_SERVICE);
mNsdManager.registerService(mNsdServiceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
第2步创建NsdServiceInfo,调用各种set方法,是为了给客户端信息,客户端通过get方法可以拿到相应的信息。
第4步注册中的NsdManager.PROTOCOL_DNS_SD是基于Dns的服务发现协议。
Nsd客户端
步骤
-
NsdManager
初始化nsdManager = (NsdManager) getSystemService(NSD_SERVICE);
- 创建两个监听器。分别是
ResolveListener
和DiscoveryListener
分别来监听NsdServiceInfo的信息和服务的链接成功和失败。
private void createResolverListener() {
mResolverListener = new NsdManager.ResolveListener() {
@Override
public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) {
Toast.makeText(MainActivity.this, "onResolveFailed", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {
mNsdServiceInfo = nsdServiceInfo;
}
};
}
private void createDiscoverListener() {
mDiscoveryListener = new NsdManager.DiscoveryListener() {
@Override
public void onStartDiscoveryFailed(String s, int i) {
Toast.makeText(MainActivity.this, "onStartDiscoveryFailed", Toast.LENGTH_SHORT).show();
}
@Override
public void onStopDiscoveryFailed(String s, int i) {
Toast.makeText(MainActivity.this, "onStopDiscoveryFailed", Toast.LENGTH_SHORT).show();
}
@Override
public void onDiscoveryStarted(String s) {
Toast.makeText(MainActivity.this, "onDiscoveryStarted", Toast.LENGTH_SHORT).show();
}
@Override
public void onDiscoveryStopped(String s) {
Toast.makeText(MainActivity.this, "onDiscoveryStopped", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceFound(NsdServiceInfo nsdServiceInfo) {
mmNsdServiceInfo = nsdServiceInfo;
//这里的nsdServiceInfo只能获取到名字,ip和端口都不能获取到,要想获取到需要调用NsdManager.resolveService方法
Toast.makeText(MainActivity.this, "onServiceFound", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
Toast.makeText(MainActivity.this, "onServiceLost", Toast.LENGTH_SHORT).show();
}
};
}
DiscoveryListener
这个监听中的NsdServiceInfo只能获取到名字,ip和端口都不能获取到,要想获取到需要调用NsdManager.resolveService方法。
- 发现周边的NSD相关网络
nsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
第一个参数要和NSD服务器端定的ServerType一样.
第二个参数是固定的
第三个参数是扫描监听器
- 主动调用resolveService方法
nsdManager.resolveService(mmNsdServiceInfo, mResolverListener);
主动调用该方法,会触发
ResolveListener()
,从而获取到NsdServiceInfo信息。
- 需要停止时调用
nsdManager.stopServiceDiscovery(mDiscoveryListener);