zoukankan      html  css  js  c++  java
  • 使用JmDNS发现设备

    JmDNS是mDNS的Java实现,以下代码演示如何使用JmDNS发现设备。

    依赖

    1 implementation "org.jmdns:jmdns:3.5.5"

    回调:

    1 import org.json.JSONArray;
    2 
    3 public interface MdnsCallback {
    4     void onDeviceFind(JSONArray jsonArray);
    5 }

    设备发现:

      1 import android.content.Context;
      2 import android.net.wifi.WifiInfo;
      3 import android.net.wifi.WifiManager;
      4 
      5 import org.json.JSONArray;
      6 import org.json.JSONObject;
      7 
      8 import java.net.InetAddress;
      9 import java.net.UnknownHostException;
     10 import java.nio.charset.StandardCharsets;
     11 import java.util.HashMap;
     12 import java.util.Map;
     13 import java.util.Objects;
     14 
     15 import javax.jmdns.JmDNS;
     16 import javax.jmdns.ServiceEvent;
     17 import javax.jmdns.ServiceInfo;
     18 import javax.jmdns.ServiceListener;
     19 
     20 public class MdnsDiscover {
     21 
     22     private Context mContext;
     23     private String mServiceName;
     24     private JmDNS mJmdns;
     25     private MdnsSearchThread mSearchThread;
     26     private MdnsCallback mCallback;
     27     private Map<String, JSONObject> jsonMap = new HashMap<>();
     28 
     29     public MdnsDiscover(Context context) {
     30         mContext = context;
     31     }
     32 
     33     public void startSearch(String serviceName, MdnsCallback callback) {
     34         mCallback = callback;
     35         if (mSearchThread != null && mSearchThread.isRunning()) {
     36             if (Objects.equals(mServiceName, serviceName)) {
     37                 return;
     38             }
     39             mSearchThread.interrupt();
     40         }
     41         mServiceName = serviceName;
     42         mSearchThread = new MdnsSearchThread();
     43         mSearchThread.start();
     44     }
     45 
     46     public void stopSearch() {
     47         if (mSearchThread != null && mSearchThread.isRunning()) {
     48             mSearchThread.interrupt();
     49             mSearchThread = null;
     50         }
     51     }
     52 
     53     private InetAddress getLocalIpAddress(WifiManager wifiManager) throws UnknownHostException {
     54         WifiInfo wifiInfo = wifiManager.getConnectionInfo();
     55         int intAddr = wifiInfo.getIpAddress();
     56         byte[] byteaddr = new byte[]{
     57                 (byte) (intAddr & 255),
     58                 (byte) (intAddr >> 8 & 255),
     59                 (byte) (intAddr >> 16 & 255),
     60                 (byte) (intAddr >> 24 & 255)};
     61         return InetAddress.getByAddress(byteaddr);
     62     }
     63 
     64     private class MdnsSearchThread extends Thread {
     65 
     66         private volatile boolean running = false;
     67 
     68         @Override
     69         public void run() {
     70             WifiManager wifiManager = (WifiManager) mContext.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
     71             assert wifiManager != null;
     72             WifiManager.MulticastLock multicastLock = wifiManager.createMulticastLock(getClass().getName());
     73             multicastLock.setReferenceCounted(false);
     74             multicastLock.acquire();//to receive multicast packets
     75             try {
     76                 ServiceListener listener = new JmdnsListener();
     77                 boolean crash = false;
     78                 while (running) {
     79                     try {
     80                         if (crash) {
     81                             Thread.sleep(3000L);
     82                         }
     83                         jsonMap.clear();
     84                         //
     85                         InetAddress addr = getLocalIpAddress(wifiManager);
     86                         //
     87                         mJmdns = JmDNS.create(addr);
     88                         mJmdns.addServiceListener(mServiceName, listener);
     89                         Thread.sleep(3000L);
     90                         mJmdns.removeServiceListener(mServiceName, listener);
     91                         mJmdns.close();
     92                         //
     93                         if (running) {
     94                             sendCallback();
     95                         }
     96                         crash = false;
     97                     } catch (Exception e) {
     98                         e.printStackTrace();
     99                         crash = true;
    100                     }
    101                 }
    102             } finally {
    103                 multicastLock.release();
    104             }
    105         }
    106 
    107         @Override
    108         public synchronized void start() {
    109             running = true;
    110             super.start();
    111         }
    112 
    113         @Override
    114         public void interrupt() {
    115             running = false;
    116             super.interrupt();
    117         }
    118 
    119         public boolean isRunning() {
    120             return running;
    121         }
    122     }
    123 
    124     private class JmdnsListener implements ServiceListener {
    125 
    126         public void serviceAdded(ServiceEvent ev) {
    127             mJmdns.requestServiceInfo(ev.getType(), ev.getName(), 1);
    128         }
    129 
    130         public void serviceRemoved(ServiceEvent ev) {
    131             jsonMap.remove(ev.getName());
    132         }
    133 
    134         public void serviceResolved(ServiceEvent ev) {
    135             if (!jsonMap.containsKey(ev.getName())) {
    136                 JSONObject jsonObj = toJsonObject(ev.getInfo());
    137                 jsonMap.put(ev.getName(), jsonObj);
    138             }
    139         }
    140     }
    141 
    142     private void sendCallback() {
    143         if (mCallback != null) {
    144             JSONArray jsonArray = new JSONArray();
    145             for (JSONObject jsonObj : jsonMap.values()) {
    146                 jsonArray.put(jsonObj);
    147             }
    148             mCallback.onDeviceFind(jsonArray);
    149         }
    150     }
    151 
    152     /**
    153      * mDNS数据格式解析
    154      */
    155     private JSONObject toJsonObject(ServiceInfo sInfo) {
    156         JSONObject jsonObj;
    157         try {
    158             jsonObj = new JSONObject();
    159             String ipv4 = "";
    160             if (sInfo.getInet4Addresses().length > 0) {
    161                 ipv4 = sInfo.getInet4Addresses()[0].getHostAddress();
    162             }
    163 
    164             jsonObj.put("Name", sInfo.getName());
    165             jsonObj.put("IP", ipv4);
    166             jsonObj.put("Port", sInfo.getPort());
    167 
    168             byte[] allInfo = sInfo.getTextBytes();
    169             int allLen = allInfo.length;
    170             byte fLen;
    171             for (int index = 0; index < allLen; index += fLen) {
    172                 fLen = allInfo[index++];
    173                 byte[] fData = new byte[fLen];
    174                 System.arraycopy(allInfo, index, fData, 0, fLen);
    175 
    176                 String fInfo = new String(fData, StandardCharsets.UTF_8);
    177                 if (fInfo.contains("=")) {
    178                     String[] temp = fInfo.split("=");
    179                     jsonObj.put(temp[0], temp[1]);
    180                 }
    181             }
    182         } catch (Exception e) {
    183             e.printStackTrace();
    184             jsonObj = null;
    185         }
    186         return jsonObj;
    187     }
    188 }

    初次发表博客,仅用于记录以备将来查询。如有谬误,多谢指正。

  • 相关阅读:
    css控制英文内容自动换行問題
    jquery添加select option两种代码思路比较
    C++实现单例模式
    C++实现单例模式
    windows下socket编程:区分shutdown()及closesocket()
    windows下socket编程:区分shutdown()及closesocket()
    socket关闭
    socket关闭
    C++模板的一些巧妙功能
    C++模板的一些巧妙功能
  • 原文地址:https://www.cnblogs.com/zenghm/p/12849240.html
Copyright © 2011-2022 走看看