我有一个连接到服务器的服务。此服务是Google通知的备份。我已经用C#编写了客户端,现在我想在Android中做类似的事情。
这是C#客户端的代码,用于在服务器关闭时捕获异常,获取异常时间并尝试重新连接五分钟,如果超过五分钟,则停止尝试重新连接5分钟然后再试一次。它似乎工作得很好
代码:
catch (Exception e)
{
Console.WriteLine("CONNECT " + e.Message);
if (attempts == 0)
{
connect_time = DateTime.Now;
interval_time = connect_time.AddMinutes(1);
}
double minutes = DateTime.Now.Subtract(connect_time).TotalMinutes;
if (minutes < 5.0 )
{
System.Threading.Thread.Sleep(5000);
attempts++;
}
else
{
System.Threading.Thread.Sleep(300000);
continue;
}
resetConnectionEvent.Set();
}
}
while (!stopConnections);
现在我想为Android做类似的事情。问题是我没有Android中的ManualResetEvent,这是一项服务。以下是我的Android代码:
class connectSocket implements Runnable
{
@Override
public void run()
{
do
{
try
{
IsRunning = true;
SSLContext context = SSLContext.getDefault();
socket = context.getSocketFactory().createSocket(SERVERIP, SERVERPORT);
SSLSocketFactory sf = SSLSocketFactory.getSocketFactory();
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
socket2 = (SSLSocket) sf.createSocket(socket, SERVERIP, SERVERPORT, false);
HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
SSLSession s = socket2.getSession();
Intent text_intent = new Intent("Text_view");
//
String MACAddr = Utils.getMACAddress(SocketServiceController.this,"eth0");
if (MACAddr.length() == 0)
MACAddr = Utils.getMACAddress(SocketServiceController.this,"wlan0");
if (MACAddr.length() == 0)
MACAddr = Secure.getString(SocketServiceController.this.getContentResolver(),Secure.ANDROID_ID);
System.out.println("************" + MACAddr);
//
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket2.getOutputStream())), true);
out.write("0002:" + MACAddr + "\r\n");
//
//
out.flush();
try
{
InputStream inputstream = socket2.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputstream));
readObject = reader.readLine();
String text = "";
while(readObject != "")
{
text = readObject;
createNotification("Alert", text, SocketServiceController.this);
sendBroadcast(text_intent);
readObject = reader.readLine();
}
connection_attemp = 0;
}
catch(Exception ex)
{
IsRunning = false;
createNotification("Alert","Connection is Closed", SocketServiceController.this);
stopService(new Intent(getApplicationContext(), SocketServiceController.class));
IsRunning = false;
if(connection_attemp == 0 )
{
c = Calendar.getInstance();
connect_time=c.get(Calendar.MINUTE);
}
double minutes = c.get(Calendar.MINUTE)- connect_time;
if(minutes < 5.0)
{
connection_attemp++;
System.out.println("MINUTES: " + minutes + " CONNECT TIME: " + connect_time);
Thread.sleep(5000);
System.out.println("CONNECTIO ATTEMPT : " + connection_attemp);
}
else
{
System.out.println("SLEEPING");
Thread.sleep(15000);
}
System.out.println("STARTING NEW SERVICE");
startService(new Intent(getApplicationContext(), SocketServiceController.class));
}
}
catch(Exception ex)
{
ex.printStackTrace();
IsRunning = false;
try
{
if(IsRunning != false)
socket.close();
}
catch(IOException e1)
{
e1.printStackTrace();
}
}
IsRunning = false;
}
while(!IsRunning);
我在StackOverflow上看到了一些关于使用信号量的问题但是我不熟悉它以及它是否适用于这种情况。现在,当我运行这段代码时,它有点做了我想要的但是我创建了多个连接,而不是像我第一次启动服务时那样只创建了多个连接。为了清楚起见,这是我的OnStartCommand:
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
super.onStartCommand(intent, flags, startId);
Runnable connect = new connectSocket();
if(IsRunning == true)
{
}
else
{
new Thread(connect).start();
}
return START_STICKY;
}
任何帮助将不胜感激
答案 0 :(得分:1)
首先,我认为您不需要信号量,如果您需要管理多个连接,则需要使用信号量,并且需要确保不会同时执行这些连接。
对于第二点,run方法的所有代码都在do-while循环中,这就是创建多个连接的原因,你必须将你的socket的所有配置放在循环之外,内部catch block是处理服务器重新连接的块,它应该是您使用循环的唯一部分。