我正在开发一个应用程序,它在启动时使用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()的特定部分)?
答案 0 :(得分: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);
}
};