2017-01-23 70 views
0

我正在开发一个应用程序,它在启动时使用SSDP连接到服务器并检索它的IP地址。 SSDP类不是我自己开发的,所以我可以接受任何重构建议,但是对于这个问题,我试图实现使用SSDP搜索服务器的逻辑,同时避免任何崩溃或超时异常从被抛出。如何继续使用SSDP在Android上搜索本地网络上的设备?

目前,我的演讲类使用私有的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; 

} 
} 

我的问题是,我怎么能叫请求()反复(或一个请求的特定部分()),直到我从服务器的响应?

回答

0

我用了一个Timer Task来每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); 
     } 
    }; 
相关问题