局域网内获取周围设备的ip和端口

 欢迎大家访问我的博客http://blog.csdn.net/mikejaps专注于android ios  app 开发     


  现在智能家居,物联网非常火,推进了WiFi模块的使用,出货量大为增加。据了解,现在大部分WiFi模块在第一次配置的时候是采用udp广播的方式来通讯的,手机端将路由的名称和密码通过udp 广播的方式发送给WiFi模块,这样的方式适合远程控制,在和WiFi模块近距离通讯的时候如果WiFi模块已经连上了路由,我们如何获取WiFi模块的ip,和 端口呢?下面介绍mdns协议--发现周围设备的ip和端口。

关键代码:

<pre name="code" class="java">public class DnsService extends Service implements ServiceListener,
		ServiceTypeListener {

	/**
	 * 日志标签
	 */
	private static final String TAG = "DnsService";

	/**
	 * Instance of Bonjour/Rendezvous/ZeroConf handler
	 */
	public JmDNS jmdns = null;

	/**
	 * Allows an application to receive Wifi Multicast packets.
	 */
	private MulticastLock multicastLock = null;

	private SocketBinder mBinder = new SocketBinder();

	private Handler handler;

	private List<Map<String, String>> ipList = new ArrayList<Map<String, String>>();

	public class SocketBinder extends Binder {
		public DnsService getService() {
			return DnsService.this;
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		startScan();
		return mBinder;
	}

	public void setMessageHandler(Handler h) {
		handler = h;
	}

	@Override
	public void onDestroy() {
		stopScan();
		super.onDestroy();
	}

	/**
	 * 添加完service后
	 */
	@Override
	public void serviceAdded(ServiceEvent event) {
		jmdns.getServiceInfo(event.getType(), event.getName());
		// jmdns.removeServiceTypeListener(DnsService.this);
		// JmdnsHandler.removeMessages(2000);
		// JmdnsHandler.sendEmptyMessageDelayed(2000, 5000);
	}

	/**
	 * Delegate method from mDNS when a service is removed.
	 */
	@Override
	public void serviceRemoved(ServiceEvent event) {

	}

	@SuppressLint("HandlerLeak")
	private Handler JmdnsHandler = new Handler() {
		public void handleMessage(Message msg) {
			Log.d(TAG, "serviceRemoved");
			if (jmdns == null)
				return;
			stopScan();
			startScan();
			// jmdns.unregisterAllServices();
			// // jmdns.removeServiceTypeListener(DnsService.this);
			// try {
			// jmdns.addServiceTypeListener(DnsService.this);
			// } catch (IOException e) {
			// // TODO Auto-generated catch block
			// e.printStackTrace();
			// }
		};
	};

	/**
	 * Delegate method from mDNS when a service is resolved.
	 */
	@Override
	public void serviceResolved(ServiceEvent event) {
		ServiceInfo info = event.getInfo();
		// Log.d(TAG, event.getInfo().getPropertyString("vendor"));
		Log.d(TAG, event.getInfo().getNiceTextString());

		boolean isChanged = false;
		for (int i = 0; i < info.getInet4Addresses().length; i++) {
			if (!ipList.contains(info.getInet4Addresses()[i].toString()
					.substring(1))) {

				Map<String, String> map = new HashMap<String, String>();
				map.put(info.getInet4Addresses()[i].toString().substring(1),
						event.getInfo().getName());
				ipList.add(map);
				isChanged = true;
				map = null;
			}
		}
		if (isChanged) {
			Message msg = handler.obtainMessage();
			msg.obj = ipList;
			msg.arg1 = event.getInfo().getPort();
			handler.sendMessage(msg);
		}

	}

	/**
	 * 发现服务并添加
	 */
	@Override
	public void serviceTypeAdded(ServiceEvent event) {
		if (event.getType().contains("Light"))
			jmdns.addServiceListener(event.getType(), this);

	}

	/**
	 * Delegate method from mDNS when a subtype is discovered.
	 */
	@Override
	public void subTypeForServiceTypeAdded(ServiceEvent event) {

	}

	private Thread thread;

	public void startScan() {
		thread = null;
		thread = new Thread() {
			@Override
			public void run() {
				try {
					Log.i(TAG, "开始搜索...");
					try {
						sleep(500);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					jmdns = JmDNS.create();
					jmdns.addServiceTypeListener(DnsService.this);

				} catch (IOException ex) {
					Log.e(TAG, "开始搜索...fail");
				}
			}
		};
		thread.start();
		JmdnsHandler.removeMessages(2000);
		JmdnsHandler.sendEmptyMessageDelayed(2000, 10000);
	}

	/**
	 * 停止搜索
	 */
	public void stopScan() {
		JmdnsHandler.removeMessages(2000);

		new Thread(new Runnable() {

			@Override
			public void run() {
				try {
					if (jmdns != null) {
						Log.i(TAG, "Stopping ZeroConf probe....");
						jmdns.unregisterAllServices();
						jmdns.close();
						jmdns = null;
					}
					if (multicastLock != null) {
						Log.i(TAG, "Releasing Mutlicast Lock...");
						multicastLock.release();
						multicastLock = null;
					}
				} catch (Exception ex) {
					Log.e(TAG, ex.getMessage(), ex);
				}
			}
		}).start();

	}

}

 jar包下载地址  
点击打开链接 http://download.csdn.net/detail/mikejaps/9225799 


利用jmdns发现局域网设备,在局域网内,你要通过一台主机和其他主机进行通信,你需要知道对方的ip地址,但是有些时候,你并不知道对方的ip地址,因为一般使用DHCP动态分配ip地址的局域网内,各个主机的IP地址是由DHCP服务器来帮你分配IP地址的。所以在很多情况下,你要知道对方的IP地址是比较麻烦的。 鉴于发现这篇文章最近的浏览量比较多,晚上也有不少转载,特别声明一下,文章水平可能不大够,只是我当时的一些理解,所以希望大家以批判的角度来看,然后又什么问题欢迎讨论。真心不希望误导大家^_^ mDNS就是来解决这个问题的。通过一个约定俗成的端口号,5353。(这个端口号应该是由IETF组织约定的。)每个进入局域网的主机,如果开启了mDNS服务的话,都会向局域网内的所有主机组播一个消息,我是谁,和我的IP地址是多少。然后其他也有该服务的主机就会响应,也会告诉你,它是谁,它的IP地址是多少。当然,具体实现要比这个复杂点。 比如,A主机进入局域网,开启了mDNS服务,并向mDNS服务注册一下信息:我提供FTP服务,我的IP是192.168.1.101,端口是21。当B主机进入局域网,并向B主机的mDNS服务请求,我要找局域网内FTP服务器,B主机的mDNS就会去局域网内向其他的mDNS询问,并且最终告诉你,有一个IP地址为192.168.1.101,端口号是21的主机,也就是A主机提供FTP服务,所以B主机就知道了A主机的IP地址和端口号了。 大概的原理就是这样子,mDNS提供的服务要远远多于这个,当然服务多但并不复杂。 在Apple 的设备上(电脑,笔记本,iphone,ipad等设备)都提供了这个服务。很多Linux设备也提供这个服务。Windows的设备可能没有提供,但是如果安装了iTunes之类的软件的话,也提供了这个服务。 这样就可以利用这个服务开发一些局域网内的自动发现,然后提供一些局域网内交互的应用了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值