基于Socket的TCP长连接(服务端Java+客户端Android),Service配合AIDL实现

最近公司的项目要求加入消息推送功能,由于项目用户量不是很大,推送需求不是很严格,而且是基于内网的推送,所以我舍弃了使用三方的推送服务,自己使用Socket写了推送功能,剪出一个小Demo来跟大家分享一下,有不足之处希望读者能够多多给出建议。
关于Socket的TCP和UDP协议,相信大家都是很清楚的,当然做长连接两者都是可以的,据说QQ和微信360等使用的UDP做的,使用两个Service相互监控保持不被系统杀死,但是我目前做不了他们那样的效果,如果各位有更好的办法,可以共享一下,我们言归正传。
代码还是相当粗糙的,目的是练习使用Socket。服务器端使用一个线程的集合存储不同的客户端,相关代码如下:

public class ServerDemo {

	private int count = 0;

	private boolean isStartServer = false;

	private ArrayList mThreadList = new ArrayList();



	public static void main(String[] args) throws IOException {



		ServerDemo server = new ServerDemo();

		server.start();

	}



	/**

	 * 开启服务端的Socket

	 * @throws IOException

	 */

	public void start() throws IOException {

		// 启动服务ServerSocket,设置端口号

		ServerSocket ss = new ServerSocket(9001);

		System.out.println("服务端已开启,等待客户端连接:");

		isStartServer = true;

		int socketID = 0;

		Socket socket = null;

		startMessageThread();

		while (isStartServer) {

			// 此处是一个阻塞方法,当有客户端连接时,就会调用此方法

			socket = ss.accept();

			System.out.println("客户端连接成功" + socket.getInetAddress());

			// 4. 为这个客户端的Socket数据连接

			SocketThread thread = new SocketThread(socket, socketID++);

			thread.start();

			mThreadList.add(thread);

		}

	}



	private void startMessageThread() {

		new Timer().schedule(new TimerTask() {



			@Override

			public void run() {

				try {

					for (SocketThread st : mThreadList) {// 分别向每个客户端发送消息

						if (st.socket == null || st.socket.isClosed())

							continue;

						System.out.println("客户端的userId:" + st.userId + "  消息编号:" + count);

						if (st.userId == null || "".equals(st.userId))// 如果暂时没有确定Socket对应的用户Id先不发

							continue;

						String content = "我是从服务器发来的消息:" + count;

						

						// 根据userId模拟服务端向不同的客户端推送消息

						if (count % 2 == 0) {

							if (st.userId.equals("002"))

								content = "我是从服务器发发送给用户002的消息:" + count;

							else

								continue;

						} else {

							if (st.userId.equals("001"))

								content = "我是从服务器发发送给用户001的消息:" + count;

							else

								continue;

						}

						SocketMessage message = new SocketMessage();

						message.setFrom(Custom.NAME_SERVER);

						message.setTo(Custom.NAME_CLIENT);

						message.setMessage(content);

						message.setType(Custom.MESSAGE_EVENT);

						message.setUserId(st.userId);

						BufferedWriter writer = st.writer;

						String jMessage = Util.initJsonObject(message).toString() + "\n";

						writer.write(jMessage);

						writer.flush();

						System.out.println("向客户端" + st.socket.getInetAddress() + "发送了消息:" + content);

					}

					count++;

				} catch (IOException e) {

					// TODO Auto-generated catch block

					e.printStackTrace();

				}



			}

		}, 0, 1000 * 30);//此处设置定时器目的是模仿服务端向客户端推送消息,假定每隔30秒推送一条消息



	}



	/**

	 * 关闭与SocketThread所代表的客户端的连接

	 * @param socketThread要关闭的客户端

	 * @throws IOException

	 */

	private void closeSocketClient(SocketThread socketThread) throws IOException {

		if (socketThread.socket != null && !socketThread.socket.isClosed()) {

			if (socketThread.reader != null)

				socketThread.reader.close();

			if (socketThread.writer != null)

				socketThread.writer.close();

			socketThread.socket.close();

		}

		mThreadList.remove(socketThread);

		socketThread = null;

	}



	/**

	 * 客户端Socket线程,

	 * @author 华硕

	 *

	 */

	public class SocketThread extends Thread {



		public int socketID;

		public Socket socket;//客户端的Socket

		public BufferedWriter writer;

		public BufferedReader reader;

		public String userId;//客户端的UserId

		private long lastTime;



		public SocketThread(Socket socket, int count) {

			socketID = count;

			this.socket = socket;

			lastTime = System.currentTimeMillis();

		}



		@Override

		public void run() {

			super.run();



			try {

				reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

				writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

				//循环监控读取客户端发来的消息

				while (isStartServer) {

					// 超出了发送心跳包规定时间,说明客户端已经断开连接了这时候要断开与该客户端的连接

					long interval = System.currentTimeMillis() - lastTime;

					if (interval >= (Custom.SOCKET_ACTIVE_TIME * 1000 * 4)) {

						System.out.println("客户端发包间隔时间严重延迟,可能已经断开了interval:" + interval);

						System.out.println("Custom.SOCKET_ACTIVE_TIME * 1000:" + Custom.SOCKET_ACTIVE_TIME * 1000);

						closeSocketClient(this);

						break;

					}

					if (reader.ready()) {

						lastTime = System.currentTimeMillis();

						System.out.println("收到消息,准备解析:");

						String data = reader.readLine();

						System.out.println("解析成功:" + data);

						SocketMessage from = Util.parseJson(data);

						//给UserID赋值,此处是我们项目的需求,根据客户端不同的UserId来分别进行推送

						if (userId == null || "".equals(userId))

							userId = from.getUserId();

						SocketMessage to = new SocketMessage();

						if (from.getType() == Custom.MESSAGE_ACTIVE) {//心跳包

							System.out.println("收到心跳包:" + socket.getInetAddress());

							to.setType(Custom.MESSAGE_ACTIVE);

							to.setFrom(Custom.NAME_SERVER);

							to.setTo(Custom.NAME_CLIENT);

							to.setMessage("");

							to.setUserId(userId);

							writer.write(Util.initJsonObject(to).toString() + "\n");

							writer.flush();

						} else if (from.getType() == Custom.MESSAGE_CLOSE) {//关闭包

							System.out.println("收到断开连接的包:" + socket.getInetAddress());

							to.setType(Custom.MESSAGE_CLOSE);

							to.setFrom(Custom.NAME_SERVER);

							to.setTo(Custom.NAME_CLIENT);

							to.setMessage("");

							to.setUserId(userId);

							writer.write(Util.initJsonObject(to).toString() + "\n");

							writer.flush();

							closeSocketClient(this);

							break;

						} else if (from.getType() == Custom.MESSAGE_EVENT) {//事件包,客户端可以向服务端发送自定义消息

							System.out.println("收到普通消息包:" + from.getMessage());

						}

					}

					Thread.sleep(100);

				}



			} catch (Exception e) {

				e.printStackTrace();

			}



		}

	}

}

当服务端收到客户端的连接时候,就开启线程用来接收客户端的消息(心跳包的消息或者是普通的消息),服务器端模拟消息推送,利用定时器每隔一段时间就像客户端推送一条消息。我的消息分为三种:
心跳消息,客户端每隔一段时间就会向服务器发送一条心跳消息,服务端收到之后会马上返回一条心跳消息给客户端,以此来保持连接。
普通消息,客户端与服务端的数据交互。
断开连接消息,当服务端收到客户端的断开连接消息时,会立马给客户端返回断开连接消息,同时服务端会主动与客户端断开连接,并从线程任务列表把该客户端Socket移除,只有再次连接才会被添加进来。客户端收到服务端的断开回执,也会断开连接,防止资源浪费和异常发生。
因为我专业是做Android开发的,重点说一下客户端的代码:

使用Service的持久存活来保持Socket不被意外断开

在onStartCommand方法返回START_STICKY,如果Service由于内存不够被意外杀死,那么等内存够了之后,还会重启

 @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand(Intent intent, int flags, int startId)");
//        return super.onStartCommand(intent, flags, startId);
        //当Service重启时候,判断一下,如果Socket断开了连接,但是保存的状态还是连接状态,那就是意外的断开,需要重连
        if (isServerClose() && SocketServiceSP.getInstance(SocketService.this).isSocketConnect())
            connectSocket();
        return START_STICKY;//设置START_STICKY为了使服务被意外杀死后可以重启
    }

注册广播,当Service走onDestroy()方法时候,发送广播,重启服务

 @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "onCreate()");
        SocketServiceSP.getInstance(this).saveSocketServiceStatus(true);//保存了Service的开启状态
        //收到Service被杀死的广播,立即重启
        restartBR = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Log.e(TAG, "SocketServer重启了......");
                String action = intent.getAction();
                if (!TextUtils.isEmpty(action) && action.equals("socketService_killed")) ;
                Intent sIntent = new Intent(SocketService.this, SocketService.class);
                startService(sIntent);
                SocketServiceSP.getInstance(SocketService.this).saveSocketServiceStatus(true);//保存了Service的开启状态
                //当Service重启时候,判断一下,如果Socket断开了连接,但是保存的状态还是连接状态,那就是意外的断开,需要重连
                if (isServerClose() && SocketServiceSP.getInstance(SocketService.this).isSocketConnect())
                    connectSocket();
            }
        };
        registerReceiver(restartBR, new IntentFilter("socketService_killed"));
    }
/**
     * 销毁Service同时要销毁Socket
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy()");
        if (mReadThread != null)
            mReadThread.release();
        releaseLastSocket(mSocket);
        sendBroadcast(new Intent("socketService_killed"));
        SocketServiceSP.getInstance(SocketService.this).saveSocketServiceStatus(false);
        unregisterReceiver(restartBR);
    }

Service的启动使用的startService方法启动的,为了使用户能够操作界面来连接和断开Socket,就需要Service进程与Activity进程进行交互,而这里需要用到AIDL技术,AIDL接口的方法参数使用了自定义的SocketMessage类,所以还需要实现Parcelable接口。
关于AIDL的使用,就不进行详细的介绍了,有不清楚的朋友可以私下交流
下面看一下整个Service的代码

package com.herenit.socketpushdemo.core;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.support.v7.app.NotificationCompat;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.herenit.socketpushdemo.ISocketMessageListener;
import com.herenit.socketpushdemo.ISocketServiceInterface;
import com.herenit.socketpushdemo.MainActivity;
import com.herenit.socketpushdemo.R;
import com.herenit.socketpushdemo.bean.SocketMessage;
import com.herenit.socketpushdemo.common.Custom;
import com.herenit.socketpushdemo.common.SocketServiceSP;
import com.herenit.socketpushdemo.common.Util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.ref.WeakReference;
import java.net.Socket;

/**
 * Created by HouBin on 2017/3/14.
 * 与服务器保持长连接的Service
 */

public class SocketService extends Service {
    private final String TAG = SocketService.class.getSimpleName();
    //Service实例,用于在Activity中进行连接断开发消息等图形界面化的操作

    //Socket的弱引用
    private WeakReference mSocket;

    //消息发出的时间(不管是心跳包还是普通消息,发送完就会跟新时间)
    private long sendTime = 0;

    private final int MSG_WHAT_CONNECT = 111; //连接Socket
    private final int MSG_WHAT_DISCONNECT = 112;//断开Socket
    private final int MSG_WHAT_SENDMESSAGE = 113;//发送消息

    /**
     * 处理Socket的连接断开发消息的Handler机制
     */
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_WHAT_CONNECT:
                    if (isServerClose()) {
                        connectSocket();
                    } else {
                        Toast.makeText(SocketService.this, "Socket已经连接上了", Toast.LENGTH_SHORT).show();
                    }
                    break;
                case MSG_WHAT_DISCONNECT:
                    if (isServerClose())
                        Toast.makeText(SocketService.this, "Socket已经断开了", Toast.LENGTH_SHORT).show();
                    else
                        interruptSocket();
                    break;
                case MSG_WHAT_SENDMESSAGE:
                    if (isServerClose()) {
                        Toast.makeText(SocketService.this, "请先连接Socket", Toast.LENGTH_SHORT).show();
                    } else {
                        SocketMessage socketMessage = (SocketMessage) msg.obj;
                        try {
                            SocketService.this.sendMessage(socketMessage);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                    break;
            }
        }
    };

    //读取服务器端发来的消息的线程
    private ReadThread mReadThread;

    //监控服务被杀死重启的广播,保持服务不被杀死
    private BroadcastReceiver restartBR;

    public SocketService() {
        super();
    }

    /**
     * 创建Service的同时要创建Socket
     */
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "onCreate()");
        SocketServiceSP.getInstance(this).saveSocketServiceStatus(true);//保存了Service的开启状态
        //收到Service被杀死的广播,立即重启
        restartBR = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Log.e(TAG, "SocketServer重启了......");
                String action = intent.getAction();
                if (!TextUtils.isEmpty(action) && action.equals("socketService_killed")) ;
                Intent sIntent = new Intent(SocketService.this, SocketService.class);
                startService(sIntent);
                SocketServiceSP.getInstance(SocketService.this).saveSocketServiceStatus(true);//保存了Service的开启状态
                //当Service重启时候,判断一下,如果Socket断开了连接,但是保存的状态还是连接状态,那就是意外的断开,需要重连
                if (isServerClose() && SocketServiceSP.getInstance(SocketService.this).isSocketConnect())
                    connectSocket();
            }
        };
        registerReceiver(restartBR, new IntentFilter("socketService_killed"));
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand(Intent intent, int flags, int startId)");
//        return super.onStartCommand(intent, flags, startId);
        //当Service重启时候,判断一下,如果Socket断开了连接,但是保存的状态还是连接状态,那就是意外的断开,需要重连
        if (isServerClose() && SocketServiceSP.getInstance(SocketService.this).isSocketConnect())
            connectSocket();
        return START_STICKY;//设置START_STICKY为了使服务被意外杀死后可以重启
    }


    /**
     * 客户端通过Socket与服务端建立连接
     */
    public void connectSocket() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Socket socket = new Socket(Custom.SERVER_HOST, Custom.SERVER_PORT);
                    //这里保存Socket当前已经连接上了
                    SocketServiceSP.getInstance(SocketService.this).saveSocketConnectStatus(true);
                    socket.setSoTimeout(Custom.SOCKET_CONNECT_TIMEOUT * 1000);
                    Log.e(TAG, "Socket连接成功。。。。。。");
                    mSocket = new WeakReference(socket);
                    mReadThread = new ReadThread(socket);
                    mReadThread.start();
                    mHandler.postDelayed(activeRunnable, Custom.SOCKET_ACTIVE_TIME * 1000);//开启定时器,定时发送心跳包,保持长连接
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 发送心跳包的任务
     */
    private Runnable activeRunnable = new Runnable() {
        @Override
        public void run() {
            if (System.currentTimeMillis() - sendTime >= Custom.SOCKET_ACTIVE_TIME * 1000) {
                SocketMessage message = new SocketMessage();
                message.setType(Custom.MESSAGE_ACTIVE);
                message.setMessage("");
                message.setFrom(Custom.NAME_CLIENT);
                message.setTo(Custom.NAME_SERVER);
                try {
                    if (!sendMessage(message)) {
                        if (mReadThread != null)
                            mReadThread.release();
                        releaseLastSocket(mSocket);
                        connectSocket();
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            mHandler.postDelayed(this, Custom.SOCKET_ACTIVE_TIME * 1000);
        }
    };

    /**
     * 发送消息到服务端
     *
     * @param message
     * @return
     */
    public boolean sendMessage(SocketMessage message) throws RemoteException {
        message.setUserId("001");
        if (mSocket == null || mSocket.get() == null) {
            return false;
        }
        Socket socket = mSocket.get();
        try {
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            if (!socket.isClosed()) {
                String jMessage = Util.initJsonObject(message).toString() + "\n";
                writer.write(jMessage);
                writer.flush();
                Log.e(TAG, "发送消息:" + jMessage);
                sendTime = System.currentTimeMillis();//每次发送成数据,就改一下最后成功发送的时间,节省心跳间隔时间 
                if (message.getType() == Custom.MESSAGE_EVENT) {//通知实现了消息监听器的界面,让其跟新消息列表
                    messageListener.updateMessageList(message);
                }
            } else {
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 读取消息的线程
     */
    class ReadThread extends Thread {
        private WeakReference mReadSocket;
        private boolean isStart = true;

        public ReadThread(Socket socket) {
            mReadSocket = new WeakReference(socket);
        }

        public void release() {
            isStart = false;
            releaseLastSocket(mReadSocket);
        }

        @Override
        public void run() {
            super.run();
            Socket socket = mReadSocket.get();
            if (socket != null && !socket.isClosed()) {
                try {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    while (isStart) {
                        if (reader.ready()) {
                            String message = reader.readLine();
                            Log.e(TAG, "收到消息:" + message);
                            SocketMessage sMessage = Util.parseJson(message);
                            if (sMessage.getType() == Custom.MESSAGE_ACTIVE) {//处理心跳回执

                            } else if (sMessage.getType() == Custom.MESSAGE_EVENT) {//事件消息
                                if (messageListener != null)
                                    messageListener.updateMessageList(sMessage);
                                sendNotification(sMessage);
                            } else if (sMessage.getType() == Custom.MESSAGE_CLOSE) {//断开连接消息回执
                                mHandler.removeCallbacks(activeRunnable);
                                release();
                                releaseLastSocket(mSocket);
                            }
                        }
                        Thread.sleep(100);//每隔0.1秒读取一次,节省点资源
                    }
                } catch (IOException e) {
                    release();
                    releaseLastSocket(mSocket);
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    //通知的ID,为了分开显示,需要根据Id区分
    private int nId = 0;

    /**
     * 收到时间消息,发送通知提醒
     *
     * @param sMessage
     */
    private void sendNotification(SocketMessage sMessage) {
        //为了版本兼容,使用v7包的BUILDER
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        //状态栏显示的提示,有的手机不显示
        builder.setTicker("简单的Notification");
        //通知栏标题
        builder.setContentTitle("from" + sMessage.getFrom() + "的消息");
        //通知栏内容
        builder.setContentText(sMessage.getMessage());
        //通知内容摘要
        builder.setSubText(sMessage.getUserId());
        //在通知右侧的时间下面用来展示一些其他信息
//        builder.setContentInfo("其他");
        //用来显示同种通知的数量,如果设置了ContentInfo属性,则NUmber属性会被覆盖,因为二者显示的位置相同
//        builder.setNumber(3);
        //可以点击通知栏的删除按钮
        builder.setAutoCancel(true);
        //系统状态栏显示的小图标
        builder.setSmallIcon(R.mipmap.jpush_notification_icon);
        //通知下拉显示的大图标
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
        //点击通知跳转的INTENT
        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent, 0);
        builder.setContentIntent(pendingIntent);//点击跳转
        //通知默认的声音,震动,呼吸灯
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        Notification notification = builder.build();
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.notify(nId, notification);
        nId++;
    }

    /**
     * 释放Socket,并关闭
     *
     * @param socket
     */
    private void releaseLastSocket(WeakReference socket) {
        //正常的断开连接,这里保存断开连接的状态
        SocketServiceSP.getInstance(this).saveSocketConnectStatus(false);
        if (socket != null) {
            Socket so = socket.get();
            try {
                if (so != null && !so.isClosed())
                    so.close();
                socket.clear();
                Log.e(TAG, "Socket断开连接。。。。。。");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 判断是否断开连接,断开返回true,没有返回false
     *
     * @return
     */
    public boolean isServerClose() {
        try {
            if (mSocket != null && mSocket.get() != null) {
                mSocket.get().sendUrgentData(0);//发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信
                return false;
            }
        } catch (Exception se) {
            return true;
        }
        return true;
    }

    /**
     * 销毁Service同时要销毁Socket
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy()");
        if (mReadThread != null)
            mReadThread.release();
        releaseLastSocket(mSocket);
        sendBroadcast(new Intent("socketService_killed"));
        SocketServiceSP.getInstance(SocketService.this).saveSocketServiceStatus(false);
        unregisterReceiver(restartBR);
    }

    /**
     * 对外提供的断开Socket连接的方法(向服务器发送断开的包,服务器收到后会与之断开)
     */
    public void interruptSocket() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                SocketMessage message = new SocketMessage();
                message.setType(Custom.MESSAGE_CLOSE);
                message.setMessage("");
                message.setFrom(Custom.NAME_CLIENT);
                message.setTo(Custom.NAME_SERVER);
                try {
                    sendMessage(message);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e(TAG, "onUnbind(Intent intent)");
        return super.onUnbind(intent);
    }

    @Override
    public void onRebind(Intent intent) {
        Log.e(TAG, "onBind(Intent intent)");
        super.onRebind(intent);
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "onRebind(Intent intent) ");
        return mBinder;
    }

    /**************************************************
     * AIDL
     ********************************************************/

    private ISocketMessageListener messageListener;
    private Binder mBinder = new ISocketServiceInterface.Stub() {
        private static final String ITAG = "ISocketServiceInterface";

        /**
         * 客户端要求连接Socket
         * @throws RemoteException
         */
        @Override
        public void connectSocket() throws RemoteException {
            Log.e(ITAG, "connectSocket");
            mHandler.sendEmptyMessage(MSG_WHAT_CONNECT);
        }

        /**
         * 客户端要求断开Socket连接
         * @throws RemoteException
         */
        @Override
        public void disConnectSocket() throws RemoteException {
            Log.e(ITAG, "disConnectSocket");
            mHandler.sendEmptyMessage(MSG_WHAT_DISCONNECT);
        }

        /**
         * 客户端向服务器端发送消息
         * @param message
         * @throws RemoteException
         */
        @Override
        public void sendMessage(SocketMessage message) throws RemoteException {
            Log.e(ITAG, "sendMessage");
            Message msg = Message.obtain();
            msg.what = MSG_WHAT_SENDMESSAGE;
            msg.obj = message;
            mHandler.sendMessage(msg);
        }

        /**
         * 客户端添加消息监听器,监听服务器端发来的消息
         * @param listener
         * @throws RemoteException
         */
        @Override
        public void addMessageListener(ISocketMessageListener listener) throws RemoteException {
            Log.e(ITAG, "addMessageListener");
            messageListener = listener;
        }

        @Override
        public void removeMessageListener(ISocketMessageListener listener) throws RemoteException {
            Log.e(ITAG, "removeMessageListener");
            messageListener = null;
        }
    };
}

代码的注释还是比较详细的,整体的代码大家可以去我的GitHub上下载
服务端代码
客户端代码
时间比较紧,介绍的不是很详细,很抱歉,大家有疑问就直接看整个项目或者直接联系我吧!

你可能感兴趣的:(Socket系列)