Skip to content

Instantly share code, notes, and snippets.

@rednoah
Created May 26, 2024 13:52
Show Gist options
  • Save rednoah/12c559883282255630cc9224fb533183 to your computer and use it in GitHub Desktop.
Save rednoah/12c559883282255630cc9224fb533183 to your computer and use it in GitHub Desktop.
Simple SSDP Java Client
import static java.nio.charset.StandardCharsets.*;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
public class SSDP {
public static final String MULTICAST_ADDRESS = "239.255.255.250";
public static final int PORT = 1900;
public static final String SERVICE_TYPE_ALL = "ssdp:all";
public static final String SERVICE_TYPE_DLNA_MEDIA_SERVER = "urn:schemas-upnp-org:device:MediaServer:1";
public static final int MAX_WAIT_TIME_SECONDS = 5;
private static DatagramPacket createRequest(String address, int port, String serviceType, int maxWaitTimeSeconds) throws IOException {
StringBuilder m = new StringBuilder("M-SEARCH * HTTP/1.1\r\n");
m.append("HOST: " + address + ":" + port + "\r\n");
m.append("MAN: \"ssdp:discover\"\r\n");
m.append("MX: " + maxWaitTimeSeconds + "\r\n");
m.append("ST: " + serviceType + "\r\n");
m.append("\r\n");
byte[] content = m.toString().getBytes(UTF_8);
return new DatagramPacket(content, content.length, InetAddress.getByName(address), port);
}
private static Map<String, String> parseResponse(byte[] bytes) {
Map<String, String> headers = new HashMap<String, String>();
String response = new String(bytes, UTF_8);
for (String line : response.split("\r\n")) {
String[] header = line.split(": ", 2);
if (header.length == 2) {
headers.put(header[0], header[1]);
}
}
return headers;
}
public static void discover(String serviceType, Consumer<Map<String, String>> handler) throws IOException {
discover(MULTICAST_ADDRESS, PORT, serviceType, MAX_WAIT_TIME_SECONDS, handler);
}
public static void discover(String serviceType, int maxWaitTimeSeconds, Consumer<Map<String, String>> handler) throws IOException {
discover(MULTICAST_ADDRESS, PORT, serviceType, maxWaitTimeSeconds, handler);
}
public static void discover(String address, int port, String serviceType, int maxWaitTimeSeconds, Consumer<Map<String, String>> handler) throws IOException {
DatagramPacket request = createRequest(address, port, serviceType, maxWaitTimeSeconds);
try (MulticastSocket multicastSocket = new MulticastSocket(request.getPort())) {
multicastSocket.setSoTimeout(maxWaitTimeSeconds * 1000);
multicastSocket.send(request);
byte[] buffer = new byte[2048];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try {
while (true) {
multicastSocket.receive(packet);
handler.accept(parseResponse(packet.getData()));
}
} catch (SocketTimeoutException e) {
// ignore;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment