前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SSDP协议的Android实现以及使用

SSDP协议的Android实现以及使用

作者头像
全栈程序员站长
发布2022-07-12 17:41:58
9360
发布2022-07-12 17:41:58
举报

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

前面一篇博客里面已经介绍过SSDP协议原理,本篇博客将实现实现Android上的SSDP协议。

关键技术分析:1、发送广播;须要发送送广播,所以须要使用MulticastSocket、SocketAddress、InetAddress,须要掌握。

2、SSDP数据报格式;标准的SSDP Server解析的时候对于分段的字段选用的特征码是”\r\n”,须要特别注意。

3、訪问权限;须要互联网,要在Mainfest中加入�联网的相关权限。

下面是我的源代码:

1、SSDPConstants.java

public class SSDPConstants { /* New line definition */ public static final String NEWLINE = “\r\n”; public static final String ADDRESS = “239.255.255.250”; public static final int PORT = 1900; public static final String SL_MSEARCH = “M-SEARCH * HTTP/1.1”; public static final String SL_OK = “HTTP/1.1 200 OK”; public static final String ST_Product = “ST:urn:schemas-upnp-org:device:Server:1”; public static final String Found = “ST=urn:schemas-upnp-org:device:”; public static final String Root = “ST:urn:schemas-upnp-org:device:DZBA_HomeDP:1”; }

2、SSDPSearchMsg .java

public class SSDPSearchMsg { static final String HOST = “Host:” + SSDP.ADDRESS + “:” + SSDP.PORT; static final String MAN = “Man:\”ssdp:discover\””; static final String NEWLINE = “\r\n”; int mMX = 5; /* seconds to delay response */ String mST; /* Search target */ public SSDPSearchMsg(String ST) { mST = ST; } public int getmMX() { return mMX; } public void setmMX(int mMX) { this.mMX = mMX; } public String getmST() { return mST; } public void setmST(String mST) { this.mST = mST; } @Override public String toString() { StringBuilder content = new StringBuilder(); content.append(SSDP.SL_MSEARCH).append(NEWLINE); content.append(HOST).append(NEWLINE); content.append(MAN).append(NEWLINE); content.append(“MX:” + mMX).append(NEWLINE); content.append(mST).append(NEWLINE); content.append(NEWLINE); return content.toString(); } }

3、SSDPSocket .java

public class SSDPSocket { SocketAddress mSSDPMulticastGroup; MulticastSocket mSSDPSocket; InetAddress broadcastAddress; public SSDPSocket() throws IOException { mSSDPSocket = new MulticastSocket(58000); // Bind some random port for receiving datagram broadcastAddress = InetAddress.getByName(SSDPConstants.ADDRESS); mSSDPSocket.joinGroup(broadcastAddress); } /* Used to send SSDP packet */ public void send(String data) throws IOException { DatagramPacket dp = new DatagramPacket(data.getBytes(), data.length(), broadcastAddress, SSDPConstants.PORT); mSSDPSocket.send(dp); } /* Used to receive SSDP packet */ public DatagramPacket receive() throws IOException { byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); mSSDPSocket.receive(dp); return dp; } public void close() { if (mSSDPSocket != null) { mSSDPSocket.close(); } } }

4、SSDP .java

public class SSDP { /* New line definition */ public static final String NEWLINE = “\r\n”; public static final String ADDRESS = “239.255.255.250”; public static final int PORT = 1900; public static final String ST = “ST”; public static final String LOCATION = “LOCATION”; public static final String NT = “NT”; public static final String NTS = “NTS”; /* Definitions of start line */ public static final String SL_NOTIFY = “NOTIFY * HTTP/1.1”; public static final String SL_MSEARCH = “M-SEARCH * HTTP/1.1”; public static final String SL_OK = “HTTP/1.1 200 OK”; @SuppressWarnings(“resource”) public static String parseHeaderValue(String content, String headerName) { Scanner s = new Scanner(content); s.nextLine(); // Skip the start line while (s.hasNextLine()) { String line = s.nextLine(); int index = line.indexOf(‘:’); String header = line.substring(0, index); if (headerName.equalsIgnoreCase(header.trim())) { return line.substring(index + 1).trim(); } } return null; } public static String parseHeaderValue(DatagramPacket dp, String headerName) { return parseHeaderValue(new String(dp.getData()), headerName); } @SuppressWarnings(“resource”) public static String parseStartLine(String content) { Scanner s = new Scanner(content); return s.nextLine(); } public static String parseStartLine(DatagramPacket dp) { return parseStartLine(new String(dp.getData())); } }

5、MainActivity .java

public class MainActivity extends Activity implements OnClickListener { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE); WifiManager.MulticastLock multicastLock = wm.createMulticastLock(“multicastLock”); multicastLock.setReferenceCounted(true); multicastLock.acquire(); setContentView(R.layout.activity_main); ((Button) this.findViewById(R.id.btnSendSSDPSearch)).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnSendSSDPSearch: new Thread(new Runnable() { @Override public void run() { SendMSearchMessage(); } }).start(); default: break; } } private void SendMSearchMessage() { // SSDPSearchMsg searchContentDirectory = new SSDPSearchMsg(SSDPConstants.ST_ContentDirectory); // SSDPSearchMsg searchAVTransport = new SSDPSearchMsg(SSDPConstants.ST_AVTransport); SSDPSearchMsg searchProduct = new SSDPSearchMsg(SSDPConstants.Root); SSDPSocket sock = null; try { sock = new SSDPSocket(); for (int i = 0; i < 2; i++) { // sock.send(searchContentDirectory.toString()); // sock.send(searchAVTransport.toString()); sock.send(searchProduct.toString()); // String s = “M-SEARCH * HTTP/1.1 \n HOST= 239.255.255.250:1900 \n MAN= \”ssdp:discover\” \n MX: 3 \n ST= upnp:rootdevice”; // sock.send(s); Log.i(“————-“, “发送的数据为:\n” + searchProduct.toString()); } while (true) { DatagramPacket dp = sock.receive(); // Here, I only receive the same packets I initially sent above String c = new String(dp.getData()).trim(); String ip = new String(dp.getAddress().toString()).trim(); Log.i(“————“, “接收到的数据为:\n” + c + “數據來源IP:” + ip); } } catch (IOException e) { Log.e(“M-SEARCH”, e.getMessage()); } } }

界面xml非常easy,仅仅有一个button

Mainfest.xml:

<?xml version=”1.0″ encoding=”utf-8″?> <manifest xmlns:android=”http://schemas.android.com/apk/res/android” package=”com.example.ssdp” android:versionCode=”1″ android:versionName=”1.0″ >

<uses-sdk android:minSdkVersion=”8″ android:targetSdkVersion=”18″ />

<uses-permission android:name=”android.permission.INTERNET” /> <uses-permission android:name=”android.permission.CHANGE_WIFI_MULTICAST_STATE” /> <uses-permission android:name=”android.permission.ACCESS_WIFI_STATE” /> <uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” />

<application android:allowBackup=”true” android:icon=”@drawable/ic_launcher” android:label=”@string/app_name” android:theme=”@style/AppTheme” > <activity android:name=”com.example.ssdp.MainActivity” android:label=”@string/app_name” > <intent-filter> <action android:name=”android.intent.action.MAIN” />

<category android:name=”android.intent.category.LAUNCHER” /> </intent-filter> </activity> </application>

</manifest>

使用须知:须要有Server端执行,http://download.csdn.net/detail/zhu530548851/7451201下载源代码,该源代码是js的。

将Server放于Linux系统文件夹下,进入test文件夹,运行node server.js就可以。

须要Linux安装有nodejs:sudo apt-get install nodejs

这样在执行Androidclient就能够从Log中看到来自于Server的信息了。

Android源代码在此:http://download.csdn.net/detail/zhu530548851/7451179

个人辛勤劳动成果,如有转载,请注明出处,谢谢!

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/118542.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年12月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档