from here으로 찍은 내 안드로이드 응용 프로그램에 매우 간단한 SSDP 기능을 구현하려고합니다.SSDP를 사용하여 적절한 UDP 패킷을 수신 할 수 없습니다.
내 응용 프로그램은 문제없이 관련 M-SEARCH 메시지가 포함 된 UDP 패킷을 브로드 캐스트 주소로 보냅니다. 문제는 UPNP 서버를 실행중인 다른 장치에서 적절한 응답을 다시 받아야한다는 것입니다. 웬일인지, 나는 안드로이드 장치로부터 보내어 졌던 정확한 같은 패킷만을 받고있다.
MainActivity.java UDP 패킷 전송이 실제로 난 문제에 아마 관련이없는 SSDP 방송 문자열 을 (건설에 대한
public class SSDPSocket {
SocketAddress mSSDPMulticastGroup;
MulticastSocket mSSDPSocket;
InetAddress broadcastAddress;
public SSDPSocket() throws IOException {
mSSDPSocket = new MulticastSocket(55325); //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();
}
}
}
SSDPSearchMsg.java을 수행
@Override
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.ST_Product);
SSDPSocket sock;
try {
sock = new SSDPSocket();
for (int i = 0; i < 2; i++) {
sock.send(searchContentDirectory.toString());
sock.send(searchAVTransport.toString());
sock.send(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());
System.out.println(c);
}
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("M-SEARCH", e.getMessage());
}
SSDPSocket.java 경험이있을 때만)
public class SSDPSearchMsg {
static final String HOST = "Host:" + SSDP.ADDRESS + ":" + SSDP.PORT;
static final String MAN = "Man:ssdp:discover";
static final String NEWLINE = System.getProperty("line.separator");
int mMX = 3; /* 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(mST).append(NEWLINE);
content.append("MX:" + mMX).append(NEWLINE);
content.append(NEWLINE);
return content.toString();
}
}
<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" />
내가하지 에뮬레이터에서, 실제 장치에서 응용 프로그램을 테스트하고 있습니다 : (210) 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;
/* 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 search targets */
public static final String ST_RootDevice = "St: rootdevice";
public static final String ST_ContentDirectory = "St: urn:schemas-upnp-org:service:ContentDirectory:1";
public static final String ST_AVTransport = "St: urn:schemas-upnp-org:service:AVTransport:1";
public static final String ST_Product = "St: urn:av-openhome-org:service:Product:1";
/* Definitions of notification sub type */
public static final String NTS_ALIVE = "NTS:ssdp:alive";
public static final String NTS_BYE = "NTS:ssdp:byebye";
public static final String NTS_UPDATE = "NTS:ssdp:update";
}
는 또한 매니페스트 관련 권한이 포함되어 있는지 확인했다.
도움을 주시면 감사하겠습니다.
덧글 추가 편집 :
멀티 캐스트 자체는 문제없이 작동합니다. SSDP 기능을 테스트하기 위해 BubbleUPNP라는 앱을 다운로드했습니다. 아니나 다를까, 와이어 샤크가 제대로 SSDP 프로토콜에 방송 주소로 휴대 전화에서 보낸 모든 메시지를 캡처 :
M-SEARCH * HTTP/1.1
Man: "ssdp:discover"
Mx: 3
Host: 239.255.255.250:1900
St: urn:schemas-upnp-org:service:AVTransport:1
그리고
HTTP/1.1 200 OK
ST:urn:schemas-upnp-org:service:ContentDirectory:1
USN:uuid:d5829e90-73ce-4213-9ad1-4e75dbdd0232::urn:schemas-upnp-org:service:ContentDirectory:1
Location:http://10.175.95.4:2869/upnphost/udhisapi.dll?content=uuid:d5829e90-73ce-4213-9ad1-4e75dbdd0232
OPT:"http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS:05f3dd08b4b4b5aafa1fe983fa447f49
Cache-Control:max-age=900
Server:Microsoft-Windows-NT/5.1 UPnP/1.0 UPnP-Device-Host/1.0
그래서 그래, 이것은 의심의 여지없이 응답, 구현 문제. 장치에 문제가 없습니다.
SSDP 패킷 만 보았을 때 가장 좋은 WireShark 필터는 ** (udp에 "HTTP/1.1"이 포함되어 있고 (udp에는 0a : 53 : 54 : 3a가 포함되어 있음) 또는 (udp 0a : 59 : 54 : 3a)) ** 해당 16 진수는 줄의 시작 부분에 "ST :"및 "NT :"입니다. –