socket服务器已经断开而主项目这边完全不知道,如何判断远端服务器是否已经断开连接,如果断开那么需要重新连接。
首先想到socket类的方法isClosed()、isConnected()、isInputStreamShutdown()、 isOutputStreamShutdown()等,但经过试验并查看相关文档,这些方法都是本地端的状态,无法判断远端是否已经断开连接。
然后想到是否可以通过OutputStream发送一段测试数据,如果发送失败就表示远端已经断开连接,类似ping,但是这样会影响到正常的输出数据,远端无法把正常数据和测试数据分开。
解决方法: 使用sendUrgentData,查看文档后得知它会往输出流发送一个字节的数据,只要对方Socket的SO_OOBINLINE属性没有打开,就会 自动舍弃这个字节,而SO_OOBINLINE属性默认情况下就是关闭的。
我的重连类,需要拿来就能用。
public class IsAgainConnect implements Runnable {
private static final boolean CONNECT = true;
private static final int WAIT_TIME = 5000;
private WifiLinking wifiLinking = null;
public void run() {
// TODO Auto-generated method stub
reunion();
}
public IsAgainConnect(WifiLinking wifiLinking) {
this.wifiLinking = wifiLinking;
initiate();
}
// run方法
private void reunion() {
while (CONNECT) {
holdTime(WAIT_TIME);
}
}
// 等待时间
private void holdTime(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
sendTestData();
}
// 发送测试数据
private void sendTestData() {
try {
if (wifiLinking.socket != null) {
wifiLinking.socket.sendUrgentData(0xFF);
}
} catch (IOException e) {
handle();
}
}
// 异常处理
private void handle() {
try {
Looper.prepare();
wifiLinking.socket = new Socket(WifiLinking.SERVER_IP,WifiLinking.SERVER_PORT);
Toast.makeText(wifiLinking.context, "已重新与服务器连接!",Toast.LENGTH_LONG).show();
} catch (Exception e1) {
Toast.makeText(wifiLinking.context, "与服务器无连接!", Toast.LENGTH_LONG).show();
initiate();
}
Looper.loop();
}
// 启动重连线程
private void initiate() {
Thread isAgainThread = new Thread(IsAgainConnect.this);
isAgainThread.start();
}
}