繁体   English   中英

如何继续使用SSDP在Android的本地网络上搜索设备?

[英]How to keep using SSDP to search for devices on local network on Android?

我正在开发一个在启动时使用SSDP连接到服务器并检索其IP地址的应用程序。 SSDP类不是由我开发的,因此我也可以接受其中的任何重构建议,但是对于这个问题,我正在尝试实现一种逻辑,该逻辑将继续使用SSDP搜索服务器,同时避免任何崩溃或超时异常从被抛出。

当前,我的演示者类使用私有的AsyncTask类来获取服务器的响应(在注释中称为MOTA或OTA站):

private class SearchAction extends AsyncTask<Void,Void,String>{
    Context context;

    SearchAction(Context context){
        this.context = context;
    }

    protected void onPreExecute(){
        view.changeVisibility(true);
    }

    @Override
    protected String doInBackground(Void... params) {
        //Get IP Address from MOTA Station
        SSDP ssdp = new SSDP();
        String ip = ssdp.request();
        Log.d(TAG,"IP Address is: "+ ip);
        return ip;
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    protected void onPostExecute(String ip_address){
        Log.d(TAG, "IP address is:  " + ip_address);


        if (Objects.equals(ip_address, "")) {

            view.changeVisibility(false);
            // TODO: give choice to user to enter IP address manually
        }else {
            //otherwise go to MainActivity directly
            Intent intent = new Intent(context, Main2Activity.class);
            intent.putExtra("IP", ip_address);
            view.navigateToMainActivity(intent);

        }
    }
}

SSDP类如下所示:

公共类SSDP {

public String tag = "SSDP";

//m-search string for specific OTA board
private static final String query =
        "M-SEARCH * HTTP/1.1\r\n" +
                "HOST: 239.255.255.250:1900\r\n"+
                "MAN: \"ssdp:discover\"\r\n"+
                "MX: 1\r\n"+
                "ST: urn:schemas-upnp-org:device:MediaServer:1\r\n"+  // Use for OTA Board
                //"ST: ssdp:all\r\n"+  // Use this for all UPnP Devices
                "\r\n";
private static final int port = 1900;

//ssdp to find IP address from server
public String request(){
    //response is to contain the server response in String type
    //initialize send data and receive data in bytes
    String response="";
    byte[] sendData = new byte[1024];
    byte[] receiveData = new byte[1024];
    //transfer m-search string in bytes
    sendData = query.getBytes();
    //wrap m-search data, multicast address and port number to the send package
    DatagramPacket sendPacket = null;
    try {
        sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("239.255.255.250"), port);
    } catch (UnknownHostException e) {
        Log.d(tag,"Unknown Host Exception Thrown after creating DatagramPacket to send to server");
        e.printStackTrace();
    }
    //create socket to transport data
    DatagramSocket clientSocket = null;
    try {
        clientSocket = new DatagramSocket();
    } catch (SocketException e) {
        Log.d(tag, "Socket Exception thrown when creating socket to transport data");
        e.printStackTrace();
    }
    //send out data
    try {
        if (clientSocket != null) {
            //time out is important
            clientSocket.setSoTimeout(10000);
            clientSocket.send(sendPacket);
        }
    } catch (IOException e) {
        Log.d(tag, "IOException thrown when sending data to socket");
        e.printStackTrace();
    }
    // receive data
    DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
    try {
        if (clientSocket != null) {
            clientSocket.receive(receivePacket);
        }
    } catch (IOException e) {
        Log.d(tag,"IOException thrown when receiving data");
        e.printStackTrace();
    }
    //the target package should not be empty
    //try three times

    for (int i =0; i<3; i++){
        Log.d(tag,"Checking target package to see if its empty on iteration#: "+i);
        response = new String(receivePacket.getData());
        Log.d(tag,"Response contains: "+response);
        if (response.contains("Location:")){
            break;
        }
    }


    String adress = "";
    //filter IP address from "Location"
    Matcher ma = Pattern.compile("Location: (.*)").matcher(response);
    if (ma.find()){
        adress+=ma.group(1);
        adress = adress.split("/")[2].split(":")[0];
    }

    return adress;

}
}

我的问题是,如何反复调用request()(或request()的特定部分),直到获得服务器的响应?

我使用计时器任务每5秒执行一次AsyncTask。

private Runnable ssdpTimerTask = new Runnable() {
        @Override
        public void run() {
            startStationSearch();
            Log.d(TAG,"Running SSDP search - iteration: "+ssdpIteration);
            ssdpIteration++;
            mHandler.postDelayed(ssdpTimerTask,5000);
        }
    };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM