SSDP协议的Android实现以及使用
前面一篇博客里面已经介绍过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
个人辛勤劳动成果,如有转载,请注明出处,谢谢!
SSDP协议的Android实现以及使用的更多相关文章
- MQTT协议实现Android中的消息收发
前言 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输),基于发布/订阅范式的消息协议,是一种极其简单和轻量级的消息协议,专为受限设备和低带宽.高延迟 ...
- 基于XMPP协议的Android即时通信系
以前做过一个基于XMPP协议的聊天社交软件,总结了一下.发出来. 设计基于开源的XMPP即时通信协议,采用C/S体系结构,通过GPRS无线网络用TCP协议连接到服务器,以架设开源的Openfn'e服务 ...
- Modbus工业协议在Android中的应用
现在工业信息画发展,很多工厂都需要做信息化展示,通常都是利用Android一体机来进行展示和交互. Modbus协议是全球第一个用于工业现场的总线协议,与外设交互可以采用串口通信,tcp等方式:通常在 ...
- 采用MQTT协议实现android消息推送(4)选fusesource-mqtt-client为客户端
1.简介 一个java写的mqtt客户端.项目地址: https://github.com/fusesource/mqtt-client 2.引入fusesource-mqtt-client库 Fil ...
- 采用MQTT协议实现android消息推送(2)MQTT服务端与客户端软件对比、android客户端示列表
1.服务端软件对比 https://github.com/mqtt/mqtt.github.io/wiki/servers 名称(点名进官网) 特性 简介 收费 支持的客户端语言 IBM MQ 完整的 ...
- 采用MQTT协议实现android消息推送(1)MQTT 协议简介
1.资料 mqtt官网 http://mqtt.org/ 服务端程序列表 https://github.com/mqtt/mqtt.github.io/wiki/servers 客户端库列表 http ...
- Android与服务器端数据交互(基于SOAP协议整合android+webservice)
http://www.cnblogs.com/zhangdongzi/archive/2011/04/19/2020688.html 上一节中我们通过http协议,采用HttpClient向服务器端a ...
- 采用MQTT协议实现android消息推送(3)选ActiveMQ当服务端
官网: http://activemq.apache.org/ 1.简介 强壮.快速.客户端支持多种语言的mqtt服务端软件. 2.特性 MQTT v3.1.AMQP v1.0.Stomp .Open ...
- android deep link(深度链接)与自定义协议!
此自定义仅供参考! 首先打开androidManifest.xml 在MainActivity中添加如下内容: <activity android:name=".MainActivit ...
随机推荐
- Linux文件系统与结构
一.Linux文件系统结构 /bin 二进制的缩写,用来放置可执行的二进制程序,基本命令 /boot 用来存放启动文件,kernel 和boot配置文件 /dev 用来放置设备文件 /dev/cons ...
- Adobe Acrobat 9 Pro 简体中文正式版(免激活)
软件语言:简体中文版本性质:官方正式版(免激活,非破解) Mac & PC [SN]: 1118-4018-6583-4956-2486-7805 修改 Abcpy.ini 可实现免序列号免激 ...
- Silverlight第三方控件专题
原文http://www.cnblogs.com/nasa/archive/2008/12/01/1344927.html 这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏 ...
- 柯南君:看大数据时代下的IT架构(7)消息队列之RabbitMQ--案例(routing 起航)
二.Routing(路由) (using the Java client) 在前面的学习中,构建了一个简单的日志记录系统,能够广播所有的日志给多个接收者,在该部分学习中,将添加一个新的特点,就是可以只 ...
- poj2608---几个字母映射到同一个数字
#include <stdio.h> #include <stdlib.h> #include<string.h> ]={,,,,,,,,,,,,,,,,,,,,, ...
- iOS-BLE蓝牙开发
Demo地址:WEBlueToothManager 在写这个博客之前,空余时间抽看了近一个月的文档和Demo,系统给的解释很详细,接口也比较实用,唯独有一点,对于设备 的唯一标示,网上众说纷纭,在这里 ...
- Android Studio插件之FindBugs
1.安装方法: AndroidStudio->Settigns->Plugins->Browse repositories->search "findBUgs-IDE ...
- 关于SVM一篇比较全介绍的博文
转自:http://blog.csdn.net/v_july_v/article/details/7624837 支持向量机通俗导论(理解SVM的三层境界) 前言 动笔写这个支持向量机(support ...
- 从UIImage的矩阵变换看矩阵运算的原理
1.矩阵的基本知识: struct CGAffineTransform { CGFloat a, b, c, d; CGFloat tx, ty;}; CGAffineTransform CGAf ...
- ##DAY10 UITableView基础
##DAY10 UITableView基础 UITableView继承于UIScrollView,可以滚动. UITableView的每⼀条数据对应的单元格叫做Cell,是UITableViewCel ...