使用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 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 }

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

你可能感兴趣的:(使用JmDNS发现设备)