侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

在Android上面如何使用带有心跳检测的Socket

2022-06-28 星期二 / 0 评论 / 0 点赞 / 64 阅读 / 8533 字

由于移动设备的网络的复杂性,经常会出现网络断开,如果没有心跳包的检测,客户端只会在需要发送数据的时候才知道自己已经断线,会延误,甚至丢失服务器发送过来的数据。一下简单建立一个带有心跳检测的Socket

    由于移动设备的网络的复杂性,经常会出现网络断开,如果没有心跳包的检测,客户端只会在需要发送数据的时候才知道自己已经断线,会延误,甚至丢失服务器发送过来的数据。一下简单建立一个带有心跳检测的SocketDemo。

Android 后台Servevice


package org.feng.sockettest.server;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.lang.ref.WeakReference;import java.net.Socket;import java.net.UnknownHostException;import java.util.Arrays;import android.app.Service;import android.content.Intent;import android.os.Handler;import android.os.IBinder;import android.os.RemoteException;import android.support.v4.content.LocalBroadcastManager;import android.util.Log;public class BackService extends Service {	private static final String TAG = "BackService";	private static final long HEART_BEAT_RATE = 3 * 1000;	public static final String HOST = "192.168.1.101";// "192.168.1.21";//	public static final int PORT = 9800;		public static final String MESSAGE_ACTION="org.feng.message_ACTION";	public static final String HEART_BEAT_ACTION="org.feng.heart_beat_ACTION";		private ReadThread mReadThread;	private LocalBroadcastManager mLocalBroadcastManager;	private WeakReference<Socket> mSocket;	// For heart Beat	private Handler mHandler = new Handler();	private Runnable heartBeatRunnable = new Runnable() {		@Override		public void run() {			if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {				boolean isSuccess = sendMsg("");//就发送一个/r/n过去 如果发送失败,就重新初始化一个socket				if (!isSuccess) {					mHandler.removeCallbacks(heartBeatRunnable);					mReadThread.release();					releaseLastSocket(mSocket);					new InitSocketThread().start();				}			}			mHandler.postDelayed(this, HEART_BEAT_RATE);		}	};	private long sendTime = 0L;	private IBackService.Stub iBackService = new IBackService.Stub() {		@Override		public boolean sendMessage(String message) throws RemoteException {			return sendMsg(message);		}	};	@Override	public IBinder onBind(Intent arg0) {		return iBackService;	}		@Override	public void onCreate() {		super.onCreate();		new InitSocketThread().start();		mLocalBroadcastManager=LocalBroadcastManager.getInstance(this);			}	public boolean sendMsg(String msg) {		if (null == mSocket || null == mSocket.get()) {			return false;		}		Socket soc = mSocket.get();		try {			if (!soc.isClosed() && !soc.isOutputShutdown()) {				OutputStream os = soc.getOutputStream();				String message = msg + "/r/n";				os.write(message.getBytes());				os.flush();				sendTime = System.currentTimeMillis();//每次发送成数据,就改一下最后成功发送的时间,节省心跳间隔时间			} else {				return false;			}		} catch (IOException e) {			e.printStackTrace();			return false;		}		return true;	}	private void initSocket() {//初始化Socket		try {			Socket so = new Socket(HOST, PORT);			mSocket = new WeakReference<Socket>(so);			mReadThread = new ReadThread(so);			mReadThread.start();			mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//初始化成功后,就准备发送心跳包		} catch (UnknownHostException e) {			e.printStackTrace();		} catch (IOException e) {			e.printStackTrace();		}	}	private void releaseLastSocket(WeakReference<Socket> mSocket) {		try {			if (null != mSocket) {				Socket sk = mSocket.get();				if (!sk.isClosed()) {					sk.close();				}				sk = null;				mSocket = null;			}		} catch (IOException e) {			e.printStackTrace();		}	}	class InitSocketThread extends Thread {		@Override		public void run() {			super.run();			initSocket();		}	}	// Thread to read content from Socket	class ReadThread extends Thread {		private WeakReference<Socket> mWeakSocket;		private boolean isStart = true;		public ReadThread(Socket socket) {			mWeakSocket = new WeakReference<Socket>(socket);		}		public void release() {			isStart = false;			releaseLastSocket(mWeakSocket);		}		@Override		public void run() {			super.run();			Socket socket = mWeakSocket.get();			if (null != socket) {				try {					InputStream is = socket.getInputStream();					byte[] buffer = new byte[1024 * 4];					int length = 0;					while (!socket.isClosed() && !socket.isInputShutdown()							&& isStart && ((length = is.read(buffer)) != -1)) {						if (length > 0) {							String message = new String(Arrays.copyOf(buffer,									length)).trim();							Log.e(TAG, message);							//收到服务器过来的消息,就通过Broadcast发送出去							if(message.equals("ok")){//处理心跳回复								Intent intent=new Intent(HEART_BEAT_ACTION);								mLocalBroadcastManager.sendBroadcast(intent);							}else{								//其他消息回复								Intent intent=new Intent(MESSAGE_ACTION);								intent.putExtra("message", message);								mLocalBroadcastManager.sendBroadcast(intent);							}						}					}				} catch (IOException e) {					e.printStackTrace();				}			}		}	}}



在Activity中发送以及接收数据:



package org.feng.sockettest;import java.lang.ref.WeakReference;import org.feng.sockettest.server.BackService;import org.feng.sockettest.server.IBackService;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.support.v4.content.LocalBroadcastManager;import android.view.View;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity {	private static final String TAG = "MainActivity";	private IBackService iBackService;	private ServiceConnection conn = new ServiceConnection() {		@Override		public void onServiceDisconnected(ComponentName name) {			iBackService = null;		}		@Override		public void onServiceConnected(ComponentName name, IBinder service) {			iBackService = IBackService.Stub.asInterface(service);		}	};	private TextView mResultText;	private EditText mEditText;	private Intent mServiceIntent;	class MessageBackReciver extends BroadcastReceiver {		private WeakReference<TextView> textView;		public MessageBackReciver(TextView tv) {			textView = new WeakReference<TextView>(tv);		}		@Override		public void onReceive(Context context, Intent intent) {			String action = intent.getAction();			TextView tv = textView.get();			if (action.equals(BackService.HEART_BEAT_ACTION)) {				if (null != tv) {					tv.setText("Get a heart heat");				}			} else {				String message = intent.getStringExtra("message");				tv.setText(message);			}		};	}	private MessageBackReciver mReciver;	private IntentFilter mIntentFilter;	private LocalBroadcastManager mLocalBroadcastManager;	@Override	public void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);		mResultText = (TextView) findViewById(R.id.resule_text);		mEditText = (EditText) findViewById(R.id.content_edit);		mReciver = new MessageBackReciver(mResultText);		mServiceIntent = new Intent(this, BackService.class);		mIntentFilter = new IntentFilter();		mIntentFilter.addAction(BackService.HEART_BEAT_ACTION);		mIntentFilter.addAction(BackService.MESSAGE_ACTION);	}	@Override	protected void onStart() {		super.onStart();		mLocalBroadcastManager.registerReceiver(mReciver, mIntentFilter);		bindService(mServiceIntent, conn, BIND_AUTO_CREATE);	}	@Override	protected void onStop() {		super.onStop();		unbindService(conn);		mLocalBroadcastManager.unregisterReceiver(mReciver);	}	public void onClick(View view) {		switch (view.getId()) {		case R.id.send:			String content = mEditText.getText().toString();			try {				boolean isSend = iBackService.sendMessage(content);//Send Content by socket				Toast.makeText(this, isSend ? "success" : "fail",						Toast.LENGTH_SHORT).show();				mEditText.setText("");			} catch (RemoteException e) {				e.printStackTrace();			}			break;		default:			break;		}	}}



完整项目带服务器段代码的见: http://git.oschina.net/fengcunhan/SocketTest.git

广告 广告

评论区