发出M-SEARCH命令时,提供服务的所有设备必须回复其提供的服务的IP地址。
我的手机有2个接口(其中包括):
根据我接收M-SEARCH的接口,我必须使用wifi的IP或mobiel来回复。
如何确定接收请求的接口?我正在寻找一种强有力的方法来做到这一点。寻找192.168 ...所以看起来不是一个好的解决方案。
我用这种方式听M_SEARCH:
MulticastSocket clientSocket;
clientSocket = new MulticastSocket(1900);
clientSocket.joinGroup(InetAddress.getByName("239.255.255.250") );
while(true)
{
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
clientSocket.receive(dp);
final String msg = new String(dp.getData(), 0, dp.getLength());
if (msg.contains("M-SEARCH"))
{
DatagramSocket resSocket = new DatagramSocket(null);
String req = "HTTP/1.1 200 OK\r\n";
req += "LOCATION: http://" + IP_TO_SPECIFY + "/index.html \r\n";
req += "HOST: "+android.os.Build.MODEL+"\r\n";
req += "EXT: \r\n";
req += "ST: upnp:rootdevice\r\n";
byte [] sendData = req.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, dp.getAddress(), dp.getPort());
resSocket.send(sendPacket);
resSocket.close();
}
}
答案 0 :(得分:6)
这是CheapCast正在使用的: -
package com.mobiotics.motionsdk;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.util.Scanner;
import android.content.Context;
import android.util.Log;
public class SSDP extends Thread {
/**
* Default IPv4 multicast address for SSDP messages
*/
public static final String ADDRESS = "239.255.255.250";
public static final String IPV6_LINK_LOCAL_ADDRESS = "FF02::C";
public static final String IPV6_SUBNET_ADDRESS = "FF03::C";
public static final String IPV6_ADMINISTRATIVE_ADDRESS = "FF04::C";
public static final String IPV6_SITE_LOCAL_ADDRESS = "FF05::C";
public static final String IPV6_GLOBAL_ADDRESS = "FF0E::C";
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";
/* Definitions of notification sub type */
public static final String NTS_ALIVE = "ssdp:alive";
public static final String NTS_BYEBYE = "ssdp:byebye";
public static final String NTS_UPDATE = "ssdp:update";
public static final String LOG_TAG = "SSDP";
private SocketAddress mMulticastGroupAddress = new InetSocketAddress("239.255.255.250", 1900);
private MulticastSocket mMulticastSocket;
private DatagramSocket mUnicastSocket;
private NetworkInterface mNetIf;
private Context mContext;
private boolean mRunning = false;
public SSDP(Context ctx) throws IOException {
mContext = ctx;
mNetIf = Utils.getActiveNetworkInterface();
}
@Override
public synchronized void start() {
mRunning = true;
super.start();
}
@Override
public void run() {
try {
mMulticastSocket = new MulticastSocket(1900);
mMulticastSocket.setLoopbackMode(true);
mMulticastSocket.joinGroup(mMulticastGroupAddress, mNetIf);
mUnicastSocket = new DatagramSocket(null);
mUnicastSocket.setReuseAddress(true);
mUnicastSocket.bind(new InetSocketAddress(Utils.getLocalV4Address(mNetIf),1900));
} catch (IOException e) {
Log.e(LOG_TAG, "Setup SSDP failed.", e);
}
while(mRunning) {
DatagramPacket dp = null;
try {
dp = receive();
String startLine = parseStartLine(dp);
if(startLine.equals(SL_MSEARCH)) {
String st = parseHeaderValue(dp, ST);
if(st.contains("dial-multiscreen-org:service:dial:1")) {
String responsePayload = "HTTP/1.1 200 OK\n" +
"ST: urn:dial-multiscreen-org:service:dial:1\n"+
"HOST: 239.255.255.250:1900\n"+
"EXT:\n"+
"CACHE-CONTROL: max-age=1800\n"+
"LOCATION: http://"+Utils.getLocalV4Address(mNetIf).getHostAddress()+":8008/ssdp/device-desc.xml\n" +
"CONFIGID.UPNP.ORG: 7339\n" +
"BOOTID.UPNP.ORG: 7339\n" +
"USN: uuid:"+ Installation.id(mContext)+"\n\n";
DatagramPacket response = new DatagramPacket(responsePayload.getBytes(), responsePayload.length(), new InetSocketAddress(dp.getAddress(),dp.getPort()));
mUnicastSocket.send(response);
//Log.d(LOG_TAG, "Responding to "+ dp.getAddress().getHostAddress());
}
}
} catch (IOException e) {
Log.e(LOG_TAG, "SSDP fail.", e);
}
}
Log.e(LOG_TAG, "SSDP shutdown.");
}
public synchronized void shutdown() {
mRunning = false;
}
private DatagramPacket receive() throws IOException {
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
mMulticastSocket.receive(dp);
return dp;
}
private 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;
}
private String parseHeaderValue(DatagramPacket dp, String headerName) {
return parseHeaderValue(new String(dp.getData()), headerName);
}
private String parseStartLine(String content) {
Scanner s = new Scanner(content);
return s.nextLine();
}
private String parseStartLine(DatagramPacket dp) {
return parseStartLine(new String(dp.getData()));
}
}