版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons)
本文的例子是客户端的例子,只有客户端的代码。
服务器端作为数据接收方,客户端作为数据发送方。
Socket通信断开的情况:
- 网络断开,导致socket通信断开;
- 服务端程序崩溃或者服务端没有启动,导致socket连接失败;
客户端在SocketService中实现。
public class SocketService extends Service {
private static final String TAG = "SocketService";
private static Socket mSocket;
//Hearbeat time
private long mSendTime = 0L;
//Heart rate
private static final long HEART_BEAT_RATE = 3 * 1000;
//For Heartbeat
private Handler mHandler = new Handler();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
//开启Tcp socket连接线程
new InitSocketThread().start();
}
@Override
public void onDestroy() {
super.onDestroy();
//释放连接资源
releaseLastSocket();
//移除心跳包线程
mHandler.removeCallbacks(mHeartbeatRunnable);
}
//Start Heartbeat thread
private Runnable mHeartbeatRunnable = new Runnable() {
@Override
public void run() {
if (System.currentTimeMillis() - mSendTime >= HEART_BEAT_RATE) {
//发送心跳包
//发送成功表示连接正常
//发送失败表示socket连接断开,重启socket连接线程进行连接
//sendHeartbeatPackage为发送数据
boolean isSuccess = sendHeartbeatPackage();
if (!isSuccess) {
//release last socket
mHandler.removeCallbacks(mHeartbeatRunnable);
releaseLastSocket();
//Restart to create tcp connection
new InitSocketThread().start();
}
}
//循环发送心跳包,3s一次
mHandler.postDelayed(this, HEART_BEAT_RATE);
}
};
//客户端连接socket的代码
class InitSocketThread extends Thread {
@Override
public void run() {
super.run();
try {
//Start heartbeat thread
//先启动心跳包线程,否则new socket连接失败报错直接到catch中
mHandler.postDelayed(mHeartbeatRunnable, HEART_BEAT_RATE);
mSocket = new Socket("127.0.0.1", 9898);
} catch (IOException e) {
//注意不能使用e.printStackTrace()打印异常
//使用e.printStackTrace()异常报错会导致程序报错退出,从而无法进行重连
//e.printStackTrace();
Log.i(TAG,"new Socket,IOException");
}
}
}
//发送心跳包
//心跳包的数据格式自己定义,服务端收到心跳包可以不予处理
//这里的心跳包格式:A66A0A00000000FF
public boolean sendHeartbeatPackage() {
//连接成功的情况下才发送心跳包
if( mSocket == null || mSocket.isClosed() || mSocket.isOutputShutdown() ){
return false;
}
final byte buffer[] = new byte[8];
buffer[0] = (byte)0xA6;
buffer[1] = 0x6A;
buffer[2] = 0x0A;
buffer[3] = 0x00;
buffer[4] = 0x00;
buffer[5] = 0x00;
buffer[6] = 0x00;
buffer[7] = (byte)0xFF;
new Thread(new Runnable() {
@Override
public void run() {
try {
OutputStream os = mSocket.getOutputStream();
os.write(buffer);
os.flush();
} catch (IOException e) {
//发送出错 断开socket然后进行重连
releaseLastSocket();
e.printStackTrace();
}
}
}).start();
//计算发送心跳包的时间
mSendTime = System.currentTimeMillis();
Log.i(TAG,"sendHeartbeatPackage,Heartbeats...");
return true;
}
/**
* Release socket connetion
*/
private void releaseLastSocket() {
try {
if (null != mSocket) {
if (!mSocket.isClosed()) {
mSocket.close();
}
mSocket = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务启动了,开启心跳包线程,心跳频率为3s,心跳包发送失败后表示连接已经断开了。连接断开后,执行重连线程。