From 4d2d9239d8915a030bb84cb2147774470b04bf27 Mon Sep 17 00:00:00 2001
From: zuoxiao <470321431@qq.com>
Date: 星期一, 04 三月 2024 17:21:11 +0800
Subject: [PATCH] 先上传Socket通讯相关代码 密码卡相关代码

---
 easysocket/src/main/java/com/easysocket/interfaces/conn/ISocketActionDispatch.java            |   38 
 easysocket/src/main/java/com/easysocket/connection/heartbeat/HeartManager.java                |  181 ++
 easysocket/src/main/AndroidManifest.xml                                                       |    4 
 easysocket/src/main/java/com/easysocket/interfaces/config/IMessageProtocol.java               |   20 
 easysocket/src/main/java/com/easysocket/config/EasySocketOptions.java                         |  478 ++++++
 easysocket/src/main/java/com/easysocket/interfaces/io/IReader.java                            |   32 
 easysocket/src/main/java/com/easysocket/exception/InitialExeption.java                        |   12 
 app/src/main/java/com/dayu/recharge/card/RegionCard.java                                      |    2 
 easysocket/src/main/java/com/easysocket/entity/OriginReadData.java                            |   58 
 app/src/main/java/com/dayu/recharge/activity/SysActivity.java                                 |   31 
 easysocket/src/main/java/com/easysocket/config/SocketFactory.java                             |   14 
 easysocket/src/main/java/com/easysocket/entity/basemsg/SuperCallbackResponse.java             |   13 
 easysocket/src/main/java/com/easysocket/ConnectionHolder.java                                 |  138 +
 easysocket/src/main/java/com/easysocket/interfaces/config/IConnectionSwitchListener.java      |   13 
 easysocket/src/main/java/com/easysocket/connection/action/IOAction.java                       |   11 
 easysocket/src/main/java/com/easysocket/interfaces/callback/IType.java                        |   29 
 app/build.gradle                                                                              |    2 
 easysocket/src/main/java/com/easysocket/interfaces/callback/ICallBack.java                    |   18 
 easysocket/src/main/java/com/easysocket/connection/reconnect/DefaultReConnection.java         |  148 +
 easysocket/src/main/java/com/easysocket/interfaces/io/IIOManager.java                         |   27 
 easysocket/src/main/java/com/easysocket/connection/action/SocketAction.java                   |   15 
 easysocket/src/main/java/com/easysocket/exception/RequestTimeOutException.java                |   13 
 easysocket/src/main/java/com/easysocket/entity/basemsg/SuperCallbackSender.java               |   36 
 app/src/main/java/com/dayu/recharge/activity/HomeActivity.java                                |    1 
 easysocket/src/main/java/com/easysocket/interfaces/callback/ProgressCancelListener.java       |   24 
 easysocket/build.gradle                                                                       |   29 
 easysocket/src/main/java/com/easysocket/utils/LogUtil.java                                    |   87 +
 easysocket/src/main/java/com/easysocket/connection/dispatcher/SocketActionDispatcher.java     |  221 ++
 app/src/main/res/layout/activity_parameter.xml                                                |   14 
 easysocket/src/main/java/com/easysocket/connection/dispatcher/CallbackResponseDispatcher.java |  191 ++
 easysocket/src/main/java/com/easysocket/config/DefaultX509ProtocolTrustManager.java           |   28 
 easysocket/src/main/java/com/easysocket/connection/reconnect/AbsReconnection.java             |   52 
 easysocket/src/main/java/com/easysocket/exception/NotNullException.java                       |   12 
 easysocket/src/main/java/com/easysocket/interfaces/callback/IProgressDialog.java              |   26 
 easysocket/src/main/java/com/easysocket/config/CallbackIDFactory.java                         |   18 
 easysocket/src/main/java/com/easysocket/entity/basemsg/SuperSender.java                       |    9 
 easysocket/src/main/java/com/easysocket/interfaces/conn/IConnectionManager.java               |   65 
 easysocket/src/main/java/com/easysocket/interfaces/conn/IHeartManager.java                    |   28 
 easysocket/src/main/java/com/easysocket/interfaces/conn/ISend.java                            |   25 
 easysocket/src/main/java/com/easysocket/entity/SocketAddress.java                             |   54 
 easysocket/src/main/java/com/easysocket/callback/ProgressDialogCallBack.java                  |  116 +
 easysocket/src/main/java/com/easysocket/connection/iowork/EasyWriter.java                     |  151 +
 easysocket/src/main/java/com/easysocket/exception/ReadRecoverableExeption.java                |   13 
 easysocket/src/main/java/com/easysocket/connection/iowork/EasyReader.java                     |  337 ++++
 easysocket/src/main/java/com/easysocket/connection/iowork/IOManager.java                      |   98 +
 easysocket/src/main/java/com/easysocket/entity/basemsg/ISender.java                           |   11 
 easysocket/src/main/java/com/easysocket/callback/SimpleCallBack.java                          |   29 
 easysocket/src/main/java/com/easysocket/utils/Utils.java                                      |  149 +
 easysocket/src/main/java/com/easysocket/connection/connect/TcpConnection.java                 |  141 +
 easysocket/src/main/java/com/easysocket/entity/basemsg/IResponse.java                         |    9 
 easysocket/src/main/java/com/easysocket/config/DefaultMessageProtocol.java                    |   28 
 app/src/main/java/com/dayu/recharge/activity/ParameterActivity.java                           |    8 
 easysocket/src/main/java/com/easysocket/interfaces/conn/ISocketActionListener.java            |   52 
 settings.gradle                                                                               |    2 
 easysocket/src/main/java/com/easysocket/EasySocket.java                                       |  340 ++++
 easysocket/src/main/java/com/easysocket/interfaces/conn/ISubscribeSocketAction.java           |   20 
 app/src/main/AndroidManifest.xml                                                              |    1 
 easysocket/src/main/java/com/easysocket/interfaces/io/IWriter.java                            |   38 
 easysocket/src/main/java/com/easysocket/callback/SuperCallBack.java                           |   44 
 app/src/main/java/com/dayu/recharge/card/PassWordCard.java                                    |   13 
 easysocket/src/main/java/com/easysocket/config/SocketSSLConfig.java                           |   81 +
 easysocket/src/main/java/com/easysocket/interfaces/conn/IReconnListener.java                  |   20 
 easysocket/src/main/java/com/easysocket/connection/action/SocketStatus.java                   |   17 
 app/src/main/res/layout/activity_admin.xml                                                    |   38 
 easysocket/src/main/java/com/easysocket/connection/dispatcher/MainThreadExecutor.java         |   21 
 easysocket/src/main/java/com/easysocket/exception/RequestCancelException.java                 |   13 
 easysocket/src/main/java/com/easysocket/connection/connect/SuperConnection.java               |  356 ++++
 easysocket/src/main/java/com/easysocket/exception/ReadUnrecoverableException.java             |   12 
 easysocket/src/main/java/com/easysocket/interfaces/conn/SocketActionListener.java             |   57 
 easysocket/src/main/java/com/easysocket/utils/HexUtil.java                                    |  275 +++
 easysocket/src/main/java/com/easysocket/interfaces/config/IOptions.java                       |   22 
 71 files changed, 4,722 insertions(+), 7 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index 9f64280..390c27d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -75,7 +75,7 @@
     implementation 'com.wang.avi:library:2.1.3'
     //鍦板潃閫夋嫨
     implementation project(':pickerviewlibrary')
-
+    implementation project(':easysocket')
     implementation 'com.tencent.bugly:crashreport:latest.release'
 //    澶勭悊鍥剧墖
 //    implementation (name: 'ocr-library', ext: 'aar')
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 39721f4..a90c515 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -116,6 +116,7 @@
         <activity android:name=".activity.IdentifyingActivity" />
         <activity android:name=".activity.ReplacementActivity" />
         <activity android:name=".activity.RechargeDetail" />
+        <activity android:name=".activity.PasswordCardActivity" />
 
 
         <meta-data
diff --git a/app/src/main/java/com/dayu/recharge/activity/HomeActivity.java b/app/src/main/java/com/dayu/recharge/activity/HomeActivity.java
index 33d033f..8ea87ae 100644
--- a/app/src/main/java/com/dayu/recharge/activity/HomeActivity.java
+++ b/app/src/main/java/com/dayu/recharge/activity/HomeActivity.java
@@ -79,6 +79,7 @@
                 startActivity(new Intent(HomeActivity.this, ReadCardAcitivy.class));
             }
         });
+        //绠$悊绯荤粺鐣岄潰
         homeBinding.homeAdmin.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
diff --git a/app/src/main/java/com/dayu/recharge/activity/ParameterActivity.java b/app/src/main/java/com/dayu/recharge/activity/ParameterActivity.java
index 283e26a..1838e59 100644
--- a/app/src/main/java/com/dayu/recharge/activity/ParameterActivity.java
+++ b/app/src/main/java/com/dayu/recharge/activity/ParameterActivity.java
@@ -57,5 +57,13 @@
                 startActivity(intent);
             }
         });
+        //瀵嗙爜鍗¤缃瘑鐮�
+        binding.parameterPassWordCard.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(ParameterActivity.this, PasswordCardActivity.class);
+                startActivity(intent);
+            }
+        });
     }
 }
diff --git a/app/src/main/java/com/dayu/recharge/activity/SysActivity.java b/app/src/main/java/com/dayu/recharge/activity/SysActivity.java
index 5bffa64..d3222ec 100644
--- a/app/src/main/java/com/dayu/recharge/activity/SysActivity.java
+++ b/app/src/main/java/com/dayu/recharge/activity/SysActivity.java
@@ -11,10 +11,12 @@
 import com.dayu.recharge.card.ConfigureDeviceRegistrationCrad;
 import com.dayu.recharge.card.DomainCard;
 import com.dayu.recharge.card.ManageCard;
+import com.dayu.recharge.card.PassWordCard;
 import com.dayu.recharge.card.RegisteredCard;
 import com.dayu.recharge.card.TestCard;
 import com.dayu.recharge.databinding.ActivityAdminBinding;
 import com.dayu.recharge.dbBean.DomainBean;
+import com.dayu.recharge.dbBean.PassWordCardBean;
 import com.dayu.recharge.dbBean.PowerBean;
 import com.dayu.recharge.utils.TipUtil;
 
@@ -99,6 +101,8 @@
                 startActivity(intent);
             }
         });
+
+        //鍒朵綔娴嬭瘯鍗�
         adminBinding.adminTest.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -108,6 +112,8 @@
                 startActivity(intent);
             }
         });
+
+        //鍒朵綔閰嶇疆璁惧淇℃伅鍗�
         adminBinding.adminConfigDeviceRegistration.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -118,6 +124,7 @@
             }
         });
 
+        //鍒朵綔閰嶇疆姘存车鍔熺巼鍗�
         adminBinding.adminConfigPower.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
@@ -135,6 +142,30 @@
             }
         });
 
+
+        adminBinding.adminPassWordCard.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                PassWordCardBean powerBean = baseDao.passWordCardDao().findFirst();
+                if (powerBean != null) {
+                    Intent intent = new Intent(SysActivity.this, NFCWreatActivity.class);
+                    PassWordCard passWordCard = new PassWordCard();
+                    passWordCard.setPassWord(powerBean.getPassWord());
+                    intent.putExtra("passWordCard", passWordCard);
+                    startActivity(intent);
+                } else {
+                    TipUtil.show("璇峰厛璁剧疆鍗″瘑鐮�");
+                }
+            }
+        });
+
+        //鍒朵綔鍖哄煙琛ㄥ彿鍗�
+        adminBinding.adminRegionCard.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+
+            }
+        });
     }
 
 
diff --git a/app/src/main/java/com/dayu/recharge/card/PassWordCard.java b/app/src/main/java/com/dayu/recharge/card/PassWordCard.java
index 40d038b..dfb7f81 100644
--- a/app/src/main/java/com/dayu/recharge/card/PassWordCard.java
+++ b/app/src/main/java/com/dayu/recharge/card/PassWordCard.java
@@ -3,20 +3,27 @@
 import com.dayu.recharge.tools.HexUtil;
 import com.dayu.recharge.utils.MyCommon;
 
+import java.io.Serializable;
 import java.util.List;
 
 /**
- * Copyright (C), 2023,
+ * Copyright (C), 2024,
  * Author: zuo
- * Date: 2023-11-08 11:22
+ * Date: 2024-3-04 11:22
  * Description:瀵嗙爜鍗�
  */
-public class PassWordCard {
+public class PassWordCard implements Serializable {
     public String cardType = MyCommon.PASS_WORD_CRAD_TYPE;//鍗$被鍨�
     public String cardData = "A0B1C289";//鏍囪瘑鐮�
     public String passWord;//鍏綅鐨勫瘑鐮�
 
+    public String getPassWord() {
+        return passWord;
+    }
 
+    public void setPassWord(String passWord) {
+        this.passWord = passWord;
+    }
 
     public static PassWordCard getBean(List<byte[]> data){
 
diff --git a/app/src/main/java/com/dayu/recharge/card/RegionCard.java b/app/src/main/java/com/dayu/recharge/card/RegionCard.java
index 8656269..9adf9b7 100644
--- a/app/src/main/java/com/dayu/recharge/card/RegionCard.java
+++ b/app/src/main/java/com/dayu/recharge/card/RegionCard.java
@@ -10,7 +10,7 @@
  * author: zuo
  * Date: 2024-02-29
  * Time: 16:29
- * 澶囨敞锛氬尯鍩熸爣鍙峰崱
+ * 澶囨敞锛氬尯鍩熻〃鍙峰崱
  */
 public class RegionCard implements Serializable {
 
diff --git a/app/src/main/res/layout/activity_admin.xml b/app/src/main/res/layout/activity_admin.xml
index 6e87394..ca72490 100644
--- a/app/src/main/res/layout/activity_admin.xml
+++ b/app/src/main/res/layout/activity_admin.xml
@@ -52,6 +52,7 @@
                 android:layout_marginLeft="20dp"
                 android:layout_marginTop="20dp"
                 android:padding="5dp"
+                android:visibility="gone"
                 android:text="鍒朵綔閲嶆柊娉ㄥ唽璁惧鍗�"
                 android:textColor="@color/text_selecter"
                 android:textSize="@dimen/text_size" />
@@ -63,6 +64,7 @@
                 android:layout_marginLeft="20dp"
                 android:layout_marginTop="20dp"
                 android:padding="5dp"
+                android:visibility="gone"
                 android:text="鍒朵綔鍒犻櫎鍏ㄩ儴鐢ㄦ埛鍗�"
                 android:textColor="@color/text_selecter"
                 android:textSize="@dimen/text_size" />
@@ -75,6 +77,7 @@
                 android:layout_marginTop="20dp"
                 android:padding="5dp"
                 android:text="鍒朵綔璁剧疆鍩熷悕鍗�"
+                android:visibility="gone"
                 android:textColor="@color/text_selecter"
                 android:textSize="@dimen/text_size" />
 
@@ -87,6 +90,7 @@
                 android:layout_marginTop="20dp"
                 android:padding="5dp"
                 android:text="鍒朵綔娴嬭瘯鍗�"
+                android:visibility="gone"
                 android:textColor="@color/text_selecter"
                 android:textSize="@dimen/text_size" />
 
@@ -98,6 +102,18 @@
                 android:layout_marginTop="20dp"
                 android:padding="5dp"
                 android:text="鍒朵綔閰嶇疆璁惧淇℃伅鍗�"
+                android:visibility="gone"
+                android:textColor="@color/text_selecter"
+                android:textSize="@dimen/text_size" />
+
+            <TextView
+                android:id="@+id/admin_passWordCard"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="20dp"
+                android:layout_marginTop="20dp"
+                android:padding="5dp"
+                android:text="鍒朵綔瀵嗙爜鍗�"
                 android:textColor="@color/text_selecter"
                 android:textSize="@dimen/text_size" />
 
@@ -111,6 +127,28 @@
                 android:text="鍒朵綔閰嶇疆姘存车鍔熺巼鍗�"
                 android:textColor="@color/text_selecter"
                 android:textSize="@dimen/text_size" />
+
+            <TextView
+                android:id="@+id/admin_blackCard"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="20dp"
+                android:layout_marginTop="20dp"
+                android:padding="5dp"
+                android:text="鍒朵綔榛戝崱"
+                android:textColor="@color/text_selecter"
+                android:textSize="@dimen/text_size" />
+
+            <TextView
+                android:id="@+id/admin_regionCard"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="20dp"
+                android:layout_marginTop="20dp"
+                android:padding="5dp"
+                android:text="鍒朵綔鍖哄煙琛ㄥ彿鍗�"
+                android:textColor="@color/text_selecter"
+                android:textSize="@dimen/text_size" />
         </LinearLayout>
 
 
diff --git a/app/src/main/res/layout/activity_parameter.xml b/app/src/main/res/layout/activity_parameter.xml
index f59a95d..30d7690 100644
--- a/app/src/main/res/layout/activity_parameter.xml
+++ b/app/src/main/res/layout/activity_parameter.xml
@@ -20,6 +20,7 @@
         android:layout_marginLeft="20dp"
         android:layout_marginTop="20dp"
         android:padding="5dp"
+        android:visibility="gone"
         android:text="鍩熷悕鍗¤缃�"
         android:textColor="@color/text_selecter"
         android:textSize="@dimen/text_size" />
@@ -31,6 +32,7 @@
         android:layout_marginLeft="20dp"
         android:layout_marginTop="20dp"
         android:padding="5dp"
+        android:visibility="gone"
         android:text="姘存车鍔熺巼鍗¤缃�"
         android:textColor="@color/text_selecter"
         android:textSize="@dimen/text_size" />
@@ -46,7 +48,16 @@
         android:text="鐢甸噺鍗曚环璁剧疆"
         android:textColor="@color/text_selecter"
         android:textSize="@dimen/text_size" />
-
+    <TextView
+        android:id="@+id/parameter_PassWordCard"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="20dp"
+        android:layout_marginTop="20dp"
+        android:padding="5dp"
+        android:text="鐢甸噺鍗曚环璁剧疆"
+        android:textColor="@color/text_selecter"
+        android:textSize="@dimen/text_size" />
     <TextView
         android:id="@+id/parameter_cardIdentifying"
         android:layout_width="match_parent"
@@ -55,6 +66,7 @@
         android:layout_marginTop="20dp"
         android:padding="5dp"
         android:text="鍗℃爣璇嗙爜璁剧疆"
+        android:visibility="gone"
         android:textColor="@color/text_selecter"
         android:textSize="@dimen/text_size" />
 
diff --git a/easysocket/build.gradle b/easysocket/build.gradle
new file mode 100644
index 0000000..34c191c
--- /dev/null
+++ b/easysocket/build.gradle
@@ -0,0 +1,29 @@
+apply plugin: 'com.android.library'
+android {
+    compileSdkVersion 27
+    //buildToolsVersion rootProject.ext.android.buildToolsVersion
+
+    defaultConfig {
+        minSdkVersion 14
+        targetSdkVersion 27
+        versionCode 1
+        versionName "1.0"
+//        javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+    compileOnly 'com.google.code.gson:gson:2.2.4'
+}
+
+sourceCompatibility = "7"
+targetCompatibility = "7"
diff --git a/easysocket/src/main/AndroidManifest.xml b/easysocket/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..e18d960
--- /dev/null
+++ b/easysocket/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.socket" >
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+</manifest>
diff --git a/easysocket/src/main/java/com/easysocket/ConnectionHolder.java b/easysocket/src/main/java/com/easysocket/ConnectionHolder.java
new file mode 100644
index 0000000..f198f9f
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/ConnectionHolder.java
@@ -0,0 +1,138 @@
+package com.easysocket;
+
+import com.easysocket.config.EasySocketOptions;
+import com.easysocket.connection.connect.SuperConnection;
+import com.easysocket.connection.connect.TcpConnection;
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.interfaces.config.IConnectionSwitchListener;
+import com.easysocket.interfaces.conn.IConnectionManager;
+import com.easysocket.utils.LogUtil;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/4
+ * Note锛歴ocket杩炴帴绠$悊鍣�
+ */
+public class ConnectionHolder {
+
+    private volatile Map<String, IConnectionManager> mConnectionManagerMap = new HashMap<>();
+
+
+    private static class InstanceHolder {
+        private static final ConnectionHolder INSTANCE = new ConnectionHolder();
+    }
+
+    public static ConnectionHolder getInstance() {
+        return InstanceHolder.INSTANCE;
+    }
+
+    private ConnectionHolder() {
+        mConnectionManagerMap.clear();
+    }
+
+    /**
+     * 绉婚櫎鏌愪釜杩炴帴
+     *
+     * @param socketAddress
+     */
+    public void removeConnection(SocketAddress socketAddress) {
+        removeConnection(createKey(socketAddress));
+    }
+
+    public void removeConnection(String socketAddress) {
+        mConnectionManagerMap.remove(socketAddress);
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾SocketAddress鐨勮繛鎺ワ紝鍙傛暟閰嶇疆浣跨敤榛樿鐨�
+     *
+     * @param address
+     * @return
+     */
+    public IConnectionManager getConnection(SocketAddress address) {
+        return getConnection(createKey(address));
+    }
+
+    public IConnectionManager getConnection(String address) {
+        IConnectionManager manager = mConnectionManagerMap.get(address);
+        if (manager == null) {
+            return getConnection(address, EasySocketOptions.getDefaultOptions());
+        } else {
+            return getConnection(address, manager.getOptions());
+        }
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾SocketAddress鐨勮繛鎺�
+     *
+     * @param address
+     * @param socketOptions
+     * @return
+     */
+    public IConnectionManager getConnection(SocketAddress address, EasySocketOptions socketOptions) {
+        return getConnection(createKey(address),socketOptions);
+    }
+
+    public IConnectionManager getConnection(String address, EasySocketOptions socketOptions) {
+        IConnectionManager manager = mConnectionManagerMap.get(address);
+        if (manager != null) { // 鏈夌紦瀛�
+            manager.setOptions(socketOptions);
+            return manager;
+        } else {
+            return createNewManagerAndCache(address, socketOptions);
+        }
+    }
+
+    /**
+     * 鍒涘缓鏂扮殑杩炴帴骞剁紦瀛�
+     *
+     * @param address
+     * @param socketOptions
+     * @return
+     */
+    private IConnectionManager createNewManagerAndCache(SocketAddress address, EasySocketOptions socketOptions) {
+        SuperConnection manager = new TcpConnection(address); // 鍒涘缓杩炴帴绠$悊鍣�
+        manager.setOptions(socketOptions); // 璁剧疆鍙傛暟
+        // 杩炴帴涓绘満鐨勫垏鎹㈢洃鍚�
+        manager.setOnConnectionSwitchListener(new IConnectionSwitchListener() {
+            @Override
+            public void onSwitchConnectionInfo(IConnectionManager manager, SocketAddress oldAddress,
+                                               SocketAddress newAddress) {
+                // 鍒囨崲浜嗗彟澶栦竴涓富鏈虹殑杩炴帴锛屽垹闄ゆ棫鐨勮繛鎺ュ拰娣诲姞鏂扮殑杩炴帴
+                synchronized (mConnectionManagerMap) {
+                    // 棣栧厛鏂紑杩炴帴锛岄攢姣佺浉鍏崇嚎绋嬪拰璧勬簮
+                    LogUtil.d("---> 棣栧厛鏂紑杩炴帴锛岄攢姣佺浉鍏崇嚎绋嬪拰璧勬簮");
+                    mConnectionManagerMap.get(createKey(oldAddress)).disconnect(false);
+                    mConnectionManagerMap.remove(createKey(oldAddress));
+                    mConnectionManagerMap.put(createKey(newAddress), manager);
+                }
+            }
+        });
+
+        synchronized (mConnectionManagerMap) {
+            mConnectionManagerMap.put(createKey(address), manager);
+        }
+        return manager;
+    }
+
+    private IConnectionManager createNewManagerAndCache(String address, EasySocketOptions socketOptions) {
+        return createNewManagerAndCache(createSocketAddress(address), socketOptions);
+    }
+
+    /**
+     * @param socketAddress
+     * @return
+     */
+    private String createKey(SocketAddress socketAddress) {
+        return socketAddress.getIp() + ":" + socketAddress.getPort();
+    }
+
+    private SocketAddress createSocketAddress(String address) {
+        String[] s = address.split(":");
+        return new SocketAddress(s[0], Integer.parseInt(s[1]));
+    }
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/EasySocket.java b/easysocket/src/main/java/com/easysocket/EasySocket.java
new file mode 100644
index 0000000..4aecbd3
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/EasySocket.java
@@ -0,0 +1,340 @@
+package com.easysocket;
+
+import android.content.Context;
+
+import com.easysocket.config.EasySocketOptions;
+import com.easysocket.connection.heartbeat.HeartManager;
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.entity.basemsg.SuperCallbackSender;
+import com.easysocket.exception.InitialExeption;
+import com.easysocket.exception.NotNullException;
+import com.easysocket.interfaces.conn.IConnectionManager;
+import com.easysocket.interfaces.conn.ISocketActionListener;
+import com.easysocket.utils.LogUtil;
+
+import java.nio.charset.Charset;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/4
+ * Note锛欵asySocket API
+ */
+public class EasySocket {
+
+    /**
+     * 杩炴帴鐨勭紦瀛�
+     */
+    private static ConnectionHolder connectionHolder = ConnectionHolder.getInstance();
+    // 鍗曚緥
+    private volatile static EasySocket singleton = null;
+    /**
+     * 榛樿鐨勮繛鎺ュ弬鏁�
+     */
+    private EasySocketOptions defOptions;
+    /**
+     * 榛樿鐨勮繛鎺�
+     */
+    private IConnectionManager defConnection;
+    /**
+     * 涓婁笅鏂�
+     */
+    private Context context;
+
+    /**
+     * 鍗曚緥
+     *
+     * @return
+     */
+    public static EasySocket getInstance() {
+        if (singleton == null) {
+            synchronized (EasySocket.class) {
+                if (singleton == null) {
+                    singleton = new EasySocket();
+                }
+            }
+        }
+        return singleton;
+    }
+
+    /**
+     * 鑾峰彇涓婁笅鏂�
+     *
+     * @return
+     */
+    public Context getContext() {
+        return context;
+    }
+
+    /**
+     * 鑾峰彇榛樿鐨勯厤缃弬鏁�
+     *
+     * @return
+     */
+    public EasySocketOptions getDefOptions() {
+        return defOptions == null ? EasySocketOptions.getDefaultOptions() : defOptions;
+    }
+
+    /**
+     * 鍒涘缓socket杩炴帴锛屾杩炴帴涓洪粯璁ょ殑杩炴帴锛屽鏋滀綘鐨勯」鐩彧鏈変竴涓猄ocket杩炴帴锛屽彲浠ョ敤杩欎釜鏂规硶锛�
+     * 鍦ㄦ柟娉曚笉鎸囧畾杩炴帴鍦板潃鐨勬儏鍐典笅锛岄粯璁や娇鐢ㄩ兘鏄繖涓繛鎺ワ紝
+     * 姣斿锛� upMessage(byte[] message)銆� connect()绛�
+     *
+     * @return
+     */
+    public EasySocket createConnection(EasySocketOptions options, Context context) {
+        this.defOptions = options;
+        this.context = context;
+        SocketAddress socketAddress = options.getSocketAddress();
+        if (options.getSocketAddress() == null) {
+            throw new InitialExeption("璇峰湪鍒濆鍖栫殑鏃跺�欒缃甋ocketAddress");
+        }
+        // 濡傛灉鏈夊鐢ㄤ富鏈哄垯璁剧疆
+        if (options.getBackupAddress() != null) {
+            socketAddress.setBackupAddress(options.getBackupAddress());
+        }
+        if (defConnection == null) {
+            defConnection = connectionHolder.getConnection(socketAddress,
+                    options == null ? EasySocketOptions.getDefaultOptions() : options);
+            // 鎵ц杩炴帴
+            defConnection.connect();
+        }
+        return this;
+    }
+
+    /**
+     * 杩炴帴socket锛屼綔鐢ㄤ簬榛樿杩炴帴
+     *
+     * @return
+     */
+    public EasySocket connect() {
+        getDefconnection().connect();
+        return this;
+    }
+
+    /**
+     * @param address socket鍦板潃锛屽寘鎷琲p鍜岀鍙�
+     * @return
+     */
+    public EasySocket connect(String address) {
+        getConnection(address).connect();
+        return this;
+    }
+
+
+    /**
+     * 鍏抽棴杩炴帴锛屼綔鐢ㄤ簬榛樿杩炴帴
+     *
+     * @param isNeedReconnect 鏄惁闇�瑕侀噸杩�
+     * @return
+     */
+    public EasySocket disconnect(boolean isNeedReconnect) {
+        LogUtil.d("EasySocket--銆媎isconnect");
+        getDefconnection().disconnect(isNeedReconnect);
+        return this;
+    }
+
+
+    /**
+     * 鍏抽棴杩炴帴
+     *
+     * @param isNeedReconnect 鏄惁闇�瑕侀噸杩�
+     * @return
+     */
+    public EasySocket disconnect(String address, boolean isNeedReconnect) {
+        getConnection(address).disconnect(isNeedReconnect);
+        return this;
+    }
+
+    /**
+     * 閿�姣佽繛鎺ュ璞★紝浣滅敤浜庨粯璁よ繛鎺�
+     *
+     * @return
+     */
+    public EasySocket destroyConnection() {
+        LogUtil.d("easysocket--銆媎estroyConnection");
+        // 鏂紑杩炴帴
+        getDefconnection().disconnect(false);
+        // 绉婚櫎杩炴帴
+        connectionHolder.removeConnection(defOptions.getSocketAddress());
+        defConnection = null;
+        return this;
+    }
+
+
+    /**
+     * 閿�姣佽繛鎺ュ璞�
+     *
+     * @return
+     */
+    public EasySocket destroyConnection(String address) {
+        // 鏂紑杩炴帴
+        getConnection(address).disconnect(false);
+        // 绉婚櫎杩炴帴
+        connectionHolder.removeConnection(address);
+        return this;
+    }
+
+    /**
+     * 鍙戦�佹湁鍥炶皟鐨勬秷鎭紝浣滅敤浜庨粯璁よ繛鎺�
+     *
+     * @param sender
+     * @return
+     */
+    public IConnectionManager upCallbackMessage(SuperCallbackSender sender) {
+        getDefconnection().upCallbackMessage(sender);
+        return defConnection;
+    }
+
+    /**
+     * 鍙戦�佹湁鍥炶皟鐨勬秷鎭�
+     *
+     * @param sender
+     * @return
+     */
+    public IConnectionManager upCallbackMessage(SuperCallbackSender sender, String address) {
+        return getConnection(address).upCallbackMessage(sender);
+    }
+
+
+    /**
+     * 鍙戦�乥yte[]
+     *
+     * @param message
+     * @return
+     */
+    public IConnectionManager upMessage(byte[] message, String address) {
+        return getConnection(address).upBytes(message);
+    }
+
+    /**
+     * 鍙戦�乥yte[]锛屼綔鐢ㄤ簬榛樿杩炴帴
+     *
+     * @param message
+     * @return
+     */
+    public IConnectionManager upMessage(byte[] message) {
+        return getDefconnection().upBytes(message);
+    }
+
+
+    /**
+     * 娉ㄥ唽鐩戝惉socket琛屼负锛屼綔鐢ㄤ簬榛樿杩炴帴
+     *
+     * @param socketActionListener
+     */
+    public EasySocket subscribeSocketAction(ISocketActionListener socketActionListener) {
+        getDefconnection().subscribeSocketAction(socketActionListener);
+        return this;
+    }
+
+
+    /**
+     * 娉ㄥ唽鐩戝惉socket琛屼负
+     *
+     * @param socketActionListener
+     */
+    public EasySocket subscribeSocketAction(ISocketActionListener socketActionListener, String address) {
+        getConnection(address).subscribeSocketAction(socketActionListener);
+        return this;
+    }
+
+    /**
+     * 寮�鍚績璺虫娴嬶紝浣滅敤浜庨粯璁よ繛鎺�
+     *
+     * @param clientHeart
+     * @return
+     */
+    public EasySocket startHeartBeat(byte[] clientHeart, HeartManager.HeartbeatListener listener) {
+        getDefconnection().getHeartManager().startHeartbeat(clientHeart, listener);
+        return this;
+    }
+
+    /**
+     * 寮�鍚績璺虫娴�
+     *
+     * @param clientHeart
+     * @return
+     */
+    public EasySocket startHeartBeat(byte[] clientHeart, String address, HeartManager.HeartbeatListener listener) {
+        getConnection(address).getHeartManager().startHeartbeat(clientHeart, listener);
+        return this;
+    }
+
+
+    /**
+     * 鑾峰彇杩炴帴
+     *
+     * @return
+     */
+    public IConnectionManager getDefconnection() {
+        if (defConnection == null) {
+//            throw new NotNullException("浣犺繕娌℃湁鍒涘缓锛�" + defOptions.getSocketAddress().getIp() + ":" + defOptions.getSocketAddress().getPort()
+//                    + "鐨凷ocket鐨勮繛鎺ワ紝璇蜂娇鐢╟om.easysocket.EasySocket.connect()鏂规硶鍒涘缓涓�涓粯璁ょ殑杩炴帴");
+        }
+        return defConnection;
+    }
+
+    /**
+     * 鑾峰彇杩炴帴
+     *
+     * @return
+     */
+    public IConnectionManager getConnection(String address) {
+        IConnectionManager connectionManager = connectionHolder.getConnection(address);
+        if (connectionManager == null) {
+            throw new NotNullException("璇峰厛鍒涘缓锛�" + address + "鐨凷ocket杩炴帴");
+        }
+        return connectionManager;
+    }
+
+    /**
+     * 鍒涘缓鎸囧畾鐨剆ocket杩炴帴锛屽鏋滀綘鐨勯」鐩湁澶氫釜socket杩炴帴锛屽彲浠ョ敤杩欎釜鏂规硶鍒涘缓鏇村鐨勮繛鎺ワ紝
+     * 褰撲綘浣跨敤甯︽湁socket鍦板潃涓哄弬鏁扮殑鏂规硶鐨勬椂鍊欙紝浣滅敤鐨勫氨鏄搴旂殑杩炴帴
+     * 姣斿锛歝onnect(String address)銆� upMessage(byte[] message, String address)绛�
+     *
+     * @param socketOptions
+     * @return
+     */
+    public IConnectionManager createSpecifyConnection(EasySocketOptions socketOptions, Context context) {
+        this.context = context;
+        IConnectionManager connectionManager = connectionHolder.getConnection(socketOptions.getSocketAddress(), socketOptions == null
+                ? EasySocketOptions.getDefaultOptions() : socketOptions);
+
+        connectionManager.connect();
+        return connectionManager;
+    }
+
+    /**
+     * 鑾峰彇鎸囧畾鐨勮繛鎺�
+     *
+     * @param socketAddress
+     * @return
+     */
+    public IConnectionManager getSpecifyConnection(String socketAddress) {
+        return connectionHolder.getConnection(socketAddress);
+    }
+
+    /**
+     * 鍙戦�佹秷鎭嚦鎸囧畾鐨勮繛鎺�
+     *
+     * @param sender
+     * @param socketAddress
+     */
+    public IConnectionManager upToSpecifyConnection(byte[] sender, String socketAddress) {
+        IConnectionManager connect = getSpecifyConnection(socketAddress);
+        if (connect != null) {
+            connect.upBytes(sender);
+        }
+        return connect;
+    }
+
+    /**
+     * 鏄惁涓篸ebug
+     *
+     * @param debug
+     */
+    public void setDebug(boolean debug) {
+        EasySocketOptions.setIsDebug(debug);
+    }
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/callback/ProgressDialogCallBack.java b/easysocket/src/main/java/com/easysocket/callback/ProgressDialogCallBack.java
new file mode 100644
index 0000000..0da1ee9
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/callback/ProgressDialogCallBack.java
@@ -0,0 +1,116 @@
+
+package com.easysocket.callback;
+
+import android.app.Dialog;
+import android.content.DialogInterface;
+
+import com.easysocket.entity.OriginReadData;
+import com.easysocket.exception.RequestCancelException;
+import com.easysocket.interfaces.callback.IProgressDialog;
+import com.easysocket.interfaces.callback.ProgressCancelListener;
+
+
+/**
+ * 鑷畾涔夊甫鏈夊姞杞借繘搴︽鐨勫洖璋�
+ */
+public abstract class ProgressDialogCallBack extends SuperCallBack implements ProgressCancelListener {
+
+    private IProgressDialog progressDialog;
+    private Dialog mDialog;
+    private boolean isShowProgress = true;
+
+    /**
+     * @param
+     */
+    public ProgressDialogCallBack(IProgressDialog progressDialog, String callbackId) {
+        super(callbackId);
+        this.progressDialog = progressDialog;
+        init(false);
+        onStart();
+    }
+
+    /**
+     * 鑷畾涔夊姞杞借繘搴︽,鍙互璁剧疆鏄惁鏄剧ず寮瑰嚭妗嗭紝鏄惁鍙互鍙栨秷
+     *
+     * @param progressDialog dialog
+     * @param isShowProgress 鏄惁鏄剧ず杩涘害
+     * @param isCancel       瀵硅瘽妗嗘槸鍚﹀彲浠ュ彇娑�
+     * @param
+     */
+    public ProgressDialogCallBack(IProgressDialog progressDialog, boolean isShowProgress,
+                                  boolean isCancel, String callbackId) {
+        super(callbackId);
+        this.progressDialog = progressDialog;
+        this.isShowProgress = isShowProgress;
+        init(isCancel);
+        onStart();
+    }
+
+    /**
+     * 鍒濆鍖�
+     *
+     * @param isCancel
+     */
+    private void init(boolean isCancel) {
+        if (progressDialog == null) return;
+        mDialog = progressDialog.getDialog();
+        if (mDialog == null) return;
+        mDialog.setCancelable(isCancel);
+        if (isCancel) {
+            mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
+                @Override
+                public void onCancel(DialogInterface dialogInterface) {
+                    ProgressDialogCallBack.this.onCancelProgress();
+                }
+            });
+        }
+    }
+
+    /**
+     * 灞曠ず杩涘害妗�
+     */
+    private void showProgress() {
+        if (!isShowProgress) {
+            return;
+        }
+        if (mDialog != null && !mDialog.isShowing()) {
+            mDialog.show();
+        }
+    }
+
+    /**
+     * 鍙栨秷杩涘害妗�
+     */
+    private void dismissProgress() {
+        if (!isShowProgress) {
+            return;
+        }
+        if (mDialog != null && mDialog.isShowing()) {
+            mDialog.dismiss();
+        }
+    }
+
+    @Override
+    public void onStart() {
+        showProgress();
+    }
+
+    @Override
+    public void onCompleted() {
+        dismissProgress();
+    }
+
+    public abstract void onResponse(OriginReadData data);
+
+    @Override
+    public void onError(Exception e) {
+        onCompleted();
+    }
+
+    @Override
+    public void onCancelProgress() {
+        onCompleted();
+        onError(new RequestCancelException("缃戠粶璇锋眰琚彇娑�"));
+    }
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/callback/SimpleCallBack.java b/easysocket/src/main/java/com/easysocket/callback/SimpleCallBack.java
new file mode 100644
index 0000000..0e0c0c2
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/callback/SimpleCallBack.java
@@ -0,0 +1,29 @@
+package com.easysocket.callback;
+
+
+/**
+ * Created by LXR ON 2018/8/29.
+ */
+public abstract class SimpleCallBack extends SuperCallBack{
+
+
+    public SimpleCallBack(String callbackId) {
+        super(callbackId);
+    }
+
+    @Override
+    public void onStart() {
+    }
+
+    @Override
+    public void onCompleted() {
+
+    }
+
+    @Override
+    public void onError(Exception e) {
+
+    }
+
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/callback/SuperCallBack.java b/easysocket/src/main/java/com/easysocket/callback/SuperCallBack.java
new file mode 100644
index 0000000..cfbdde4
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/callback/SuperCallBack.java
@@ -0,0 +1,44 @@
+package com.easysocket.callback;
+
+
+import com.easysocket.entity.OriginReadData;
+
+/**
+ * Created by LXR ON 2018/8/29.
+ */
+public abstract class SuperCallBack {
+    /**
+     * 闅忔満瀛楃涓诧紝璇嗗埆鏈嶅姟绔簲绛旀秷鎭殑鍞竴鏍囪瘑
+     */
+    private String callbackId;
+
+    /**
+     * @param callbackId 璇嗗埆鏈嶅姟绔簲绛旀秷鎭殑鍞竴鏍囪瘑
+     */
+    public SuperCallBack(String callbackId) {
+        this.callbackId = callbackId;
+    }
+
+    /**
+     * 鑾峰彇鍥炶皟ID
+     *
+     * @return
+     */
+    public String getCallbackId() {
+        return callbackId;
+    }
+
+    public abstract void onStart();
+
+    public abstract void onCompleted();
+
+    public abstract void onError(Exception e);
+
+    public void onSuccess(OriginReadData data) {
+        onCompleted();
+        onResponse(data);
+    }
+
+    public abstract void onResponse(OriginReadData data);
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/config/CallbackIDFactory.java b/easysocket/src/main/java/com/easysocket/config/CallbackIDFactory.java
new file mode 100644
index 0000000..623fa5b
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/config/CallbackIDFactory.java
@@ -0,0 +1,18 @@
+package com.easysocket.config;
+
+import com.easysocket.entity.OriginReadData;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/4
+ * Note锛氳鎯冲疄鐜癊asySocket鐨勫洖璋冨姛鑳斤紝蹇呴』瀹炵幇姝ゅ伐鍘傜被锛宑allbackID浣滀负鍥炶皟娑堟伅鐨勫敮涓�鏍囪瘑
+ */
+public abstract class CallbackIDFactory {
+    /**
+     * 杩斿洖callbackID
+     *
+     * @param
+     * @return 濡傛灉娌℃湁callbackID璇疯繑鍥瀗ull
+     */
+    public abstract String getCallbackID(OriginReadData data);
+}
diff --git a/easysocket/src/main/java/com/easysocket/config/DefaultMessageProtocol.java b/easysocket/src/main/java/com/easysocket/config/DefaultMessageProtocol.java
new file mode 100644
index 0000000..7d737f9
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/config/DefaultMessageProtocol.java
@@ -0,0 +1,28 @@
+package com.easysocket.config;
+
+import com.easysocket.interfaces.config.IMessageProtocol;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/5/31
+ * Note锛氶粯璁ょ殑娑堟伅鍗忚锛宧eader涓�4涓瓧鑺傦紝淇濆瓨娑堟伅浣� body鐨勯暱搴�
+ */
+public class DefaultMessageProtocol implements IMessageProtocol {
+    @Override
+    public int getHeaderLength() {
+        return 4; // 鍖呭ご闀垮害锛岀敤鏉ヤ繚瀛榖ody鐨勯暱搴﹀��
+    }
+
+    @Override
+    public int getBodyLength(byte[] header, ByteOrder byteOrder) {
+        if (header == null || header.length < getHeaderLength()) {
+            return 0;
+        }
+        ByteBuffer bb = ByteBuffer.wrap(header);
+        bb.order(byteOrder);
+        return bb.getInt(); // body鐨勯暱搴︿互int鐨勫舰寮忎繚瀛樺湪 header
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/config/DefaultX509ProtocolTrustManager.java b/easysocket/src/main/java/com/easysocket/config/DefaultX509ProtocolTrustManager.java
new file mode 100644
index 0000000..ca7c96e
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/config/DefaultX509ProtocolTrustManager.java
@@ -0,0 +1,28 @@
+package com.easysocket.config;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/3
+ * Note锛�
+ */
+public class DefaultX509ProtocolTrustManager implements X509TrustManager {
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+
+    }
+
+    @Override
+    public X509Certificate[] getAcceptedIssuers() {
+        return new X509Certificate[0];
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/config/EasySocketOptions.java b/easysocket/src/main/java/com/easysocket/config/EasySocketOptions.java
new file mode 100644
index 0000000..0cf70b4
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/config/EasySocketOptions.java
@@ -0,0 +1,478 @@
+package com.easysocket.config;
+
+import com.easysocket.connection.reconnect.AbsReconnection;
+import com.easysocket.connection.reconnect.DefaultReConnection;
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.interfaces.config.IMessageProtocol;
+
+import java.nio.ByteOrder;
+
+/**
+ * Author锛欰lex銆�
+ * Date锛�2019/5/31銆�
+ * Note锛歴ocket鐩稿叧閰嶇疆銆�
+ */
+public class EasySocketOptions {
+
+    /**
+     * 鏄惁璋冭瘯妯″紡
+     */
+    private static boolean isDebug = true;
+    /**
+     * 涓绘満鍦板潃
+     */
+    private SocketAddress socketAddress;
+    /**
+     * 澶囩敤涓绘満鍦板潃
+     */
+    private SocketAddress backupAddress;
+    /**
+     * 鍐欏叆Socket绠¢亾鐨勫瓧鑺傚簭
+     */
+    private ByteOrder writeOrder;
+    /**
+     * 浠嶴ocket璇诲彇瀛楄妭鏃剁殑瀛楄妭搴�
+     */
+    private ByteOrder readOrder;
+    /**
+     * 浠巗ocket璇诲彇鏁版嵁鏃堕伒浠庣殑鏁版嵁鍖呯粨鏋勫崗璁紝鍦ㄤ笟鍔″眰杩涜瀹氫箟
+     */
+    private IMessageProtocol messageProtocol;
+    /**
+     * 鍐欐暟鎹椂鍗曚釜鏁版嵁鍖呯殑鏈�澶у��
+     */
+    private int maxWriteBytes;
+    /**
+     * 璇绘暟鎹椂鍗曟璇诲彇鏈�澶х紦瀛樺�硷紝鏁板�艰秺澶ф晥鐜囪秺楂橈紝浣嗘槸绯荤粺娑堣�椾篃瓒婂ぇ
+     */
+    private int maxReadBytes;
+    /**
+     * 蹇冭烦棰戠巼/姣
+     */
+    private long heartbeatFreq;
+    /**
+     * 蹇冭烦鏈�澶х殑涓㈠け娆℃暟锛屽ぇ浜庤繖涓暟鎹紝灏嗘柇寮�socket杩炴帴
+     */
+    private int maxHeartbeatLoseTimes;
+    /**
+     * 杩炴帴瓒呮椂鏃堕棿(姣)
+     */
+    private int connectTimeout;
+    /**
+     * 鏈嶅姟鍣ㄨ繑鍥炴暟鎹殑鏈�澶у�硷紙鍗曚綅Mb锛夛紝闃叉瀹㈡埛绔唴瀛樻孩鍑�
+     */
+    private int maxResponseDataMb;
+    /**
+     * socket閲嶈繛绠$悊鍣�
+     */
+    private AbsReconnection reconnectionManager;
+    /**
+     * 瀹夊叏濂楁帴瀛楃浉鍏抽厤缃�
+     */
+    private SocketSSLConfig easySSLConfig;
+    /**
+     * socket宸ュ巶
+     */
+    private SocketFactory socketFactory;
+    /**
+     * 瀹炵幇鍥炶皟鍔熻兘闇�瑕乧allbackID锛岃�宑allbackID鏄繚瀛樺湪鍙戦�佹秷鎭拰搴旂瓟娑堟伅涓殑锛屾宸ュ巶鐢ㄦ潵鑾峰彇socket娑堟伅涓�
+     * 淇濆瓨callbackID鍊肩殑key锛屾瘮濡俲son鏍煎紡涓殑key-value涓殑key
+     */
+    private CallbackIDFactory callbackIDFactory;
+    /**
+     * 璇锋眰瓒呮椂鏃堕棿锛屽崟浣嶆绉�
+     */
+    private long requestTimeout;
+    /**
+     * 鏄惁寮�鍚姹傝秴鏃舵娴�
+     */
+    private boolean isOpenRequestTimeout;
+
+    /**
+     * IO瀛楃娴佺殑缂栫爜鏂瑰紡锛岄粯璁tf-8
+     */
+    private String charsetName;
+
+    public boolean isDebug() {
+        return isDebug;
+    }
+
+
+    /**
+     * 闈欐�佸唴閮ㄧ被
+     */
+    public static class Builder {
+        EasySocketOptions socketOptions;
+
+        // 棣栧厛鑾峰緱涓�涓粯璁ょ殑閰嶇疆
+        public Builder() {
+            this(getDefaultOptions());
+        }
+
+        public Builder(EasySocketOptions defaultOptions) {
+            socketOptions = defaultOptions;
+        }
+
+        /**
+         * 璁剧疆socket 涓绘満鍦板潃
+         *
+         * @param socketAddress
+         * @return
+         */
+        public Builder setSocketAddress(SocketAddress socketAddress) {
+            socketOptions.socketAddress = socketAddress;
+            return this;
+        }
+
+        /**
+         * 璁剧疆澶囩敤鐨勪富鏈哄湴鍧�
+         *
+         * @param backupAddress
+         * @return
+         */
+        public Builder setBackupAddress(SocketAddress backupAddress) {
+            socketOptions.backupAddress = backupAddress;
+            return this;
+        }
+
+        /**
+         * 璁剧疆鏄惁寮�鍚姹傝秴鏃剁殑妫�娴�
+         *
+         * @param openRequestTimeout
+         * @return
+         */
+        public Builder setOpenRequestTimeout(boolean openRequestTimeout) {
+            socketOptions.isOpenRequestTimeout = openRequestTimeout;
+            return this;
+        }
+
+        /**
+         * 璁剧疆璇锋眰瓒呮椂鏃堕棿
+         *
+         * @param requestTimeout 姣
+         * @return
+         */
+        public Builder setRequestTimeout(long requestTimeout) {
+            socketOptions.requestTimeout = requestTimeout;
+            return this;
+        }
+
+        /**
+         * 璁剧疆璇锋眰ack鐨勫伐鍘�
+         *
+         * @param callbackIDFactory
+         */
+        public Builder setCallbackIDFactory(CallbackIDFactory callbackIDFactory) {
+            socketOptions.callbackIDFactory = callbackIDFactory;
+            return this;
+        }
+
+
+        /**
+         * 璁剧疆鍐欐暟鎹殑瀛楄妭椤哄簭
+         *
+         * @param writeOrder
+         * @return
+         */
+        public Builder setWriteOrder(ByteOrder writeOrder) {
+            socketOptions.writeOrder = writeOrder;
+            return this;
+        }
+
+        /**
+         * 璁剧疆璇绘暟鎹殑瀛楄妭椤哄簭
+         *
+         * @param readOrder
+         * @return
+         */
+        public Builder setReadOrder(ByteOrder readOrder) {
+            socketOptions.readOrder = readOrder;
+            return this;
+        }
+
+        /**
+         * 璁剧疆璇诲彇鏁版嵁鐨勬暟鎹粨鏋勫崗璁�
+         *
+         * @param readerProtocol
+         * @return
+         */
+        public Builder setReaderProtocol(IMessageProtocol readerProtocol) {
+            socketOptions.messageProtocol = readerProtocol;
+            return this;
+        }
+
+        /**
+         * 璁剧疆鍐欐暟鎹椂鍗曚釜鏁版嵁鍖呯殑鏈�澶у��
+         *
+         * @param maxWriteBytes
+         * @return
+         */
+        public Builder setMaxWriteBytes(int maxWriteBytes) {
+            socketOptions.maxWriteBytes = maxWriteBytes;
+            return this;
+        }
+
+        /**
+         * 璁剧疆璇绘暟鎹椂鍗曟璇诲彇鐨勬渶澶х紦瀛樺��
+         *
+         * @param maxReadBytes
+         * @return
+         */
+        public Builder setMaxReadBytes(int maxReadBytes) {
+            socketOptions.maxReadBytes = maxReadBytes;
+            return this;
+        }
+
+        /**
+         * 璁剧疆蹇冭烦鍙戦�侀鐜囷紝鍗曚綅姣
+         *
+         * @param heartbeatFreq
+         * @return
+         */
+        public Builder setHeartbeatFreq(long heartbeatFreq) {
+            socketOptions.heartbeatFreq = heartbeatFreq;
+            return this;
+        }
+
+        /**
+         * 璁剧疆蹇冭烦涓㈠け鐨勬渶澶у厑璁告暟锛屽鏋滆秴杩囪繖涓渶澶ф暟灏辨柇寮�socket杩炴帴
+         *
+         * @param maxHeartbeatLoseTimes
+         * @return
+         */
+        public Builder setMaxHeartbeatLoseTimes(int maxHeartbeatLoseTimes) {
+            socketOptions.maxHeartbeatLoseTimes = maxHeartbeatLoseTimes;
+            return this;
+        }
+
+        /**
+         * 璁剧疆杩炴帴瓒呮椂鏃堕棿
+         *
+         * @param connectTimeout
+         * @return
+         */
+        public Builder setConnectTimeout(int connectTimeout) {
+            socketOptions.connectTimeout = connectTimeout;
+            return this;
+        }
+
+        /**
+         * 璁剧疆鏈嶅姟鍣ㄨ繑鍥炴暟鎹殑鍏佽鐨勬渶澶у�硷紝鍗曚綅鍏�
+         *
+         * @param maxResponseDataMb
+         * @return
+         */
+        public Builder setMaxResponseDataMb(int maxResponseDataMb) {
+            socketOptions.maxResponseDataMb = maxResponseDataMb;
+            return this;
+        }
+
+        /**
+         * 璁剧疆閲嶈繛绠$悊鍣�
+         *
+         * @param reconnectionManager
+         * @return
+         */
+        public Builder setReconnectionManager(AbsReconnection reconnectionManager) {
+            socketOptions.reconnectionManager = reconnectionManager;
+            return this;
+        }
+
+        /**
+         * 瀹夊叏濂楁帴瀛楃殑閰嶇疆
+         *
+         * @param easySSLConfig
+         * @return
+         */
+        public Builder setEasySSLConfig(SocketSSLConfig easySSLConfig) {
+            socketOptions.easySSLConfig = easySSLConfig;
+            return this;
+        }
+
+        /**
+         * 鑷畾涔夊垱寤簊ocket宸ュ巶
+         *
+         * @param socketFactory
+         * @return
+         */
+        public Builder setSocketFactory(SocketFactory socketFactory) {
+            socketOptions.socketFactory = socketFactory;
+            return this;
+        }
+
+        public Builder setCharsetName(String charsetName) {
+            socketOptions.charsetName = charsetName;
+            return this;
+        }
+
+        public EasySocketOptions build() {
+            return socketOptions;
+        }
+    }
+
+
+    /**
+     * 鑾峰彇榛樿鐨勯厤缃�
+     *
+     * @return
+     */
+    public static EasySocketOptions getDefaultOptions() {
+        EasySocketOptions options = new EasySocketOptions();
+        options.socketAddress = null;
+        options.backupAddress = null;
+        options.heartbeatFreq = 5 * 1000;
+        options.messageProtocol = null;
+        options.maxResponseDataMb = 5;
+        options.connectTimeout = 5 * 1000; // 杩炴帴瓒呮椂榛樿5绉�
+        options.maxWriteBytes = 100;
+        options.maxReadBytes = 50;
+        options.readOrder = ByteOrder.BIG_ENDIAN;
+        options.writeOrder = ByteOrder.BIG_ENDIAN;
+        options.maxHeartbeatLoseTimes = 5;
+        options.reconnectionManager = new DefaultReConnection();
+        options.easySSLConfig = null;
+        options.socketFactory = null;
+        options.callbackIDFactory = null;
+        options.requestTimeout = 10 * 1000; // 榛樿鍗佺
+        options.isOpenRequestTimeout = true; // 榛樿寮�鍚�
+        options.charsetName = "UTF-8";
+        return options;
+    }
+
+    public String getCharsetName() {
+        return charsetName;
+    }
+
+    public ByteOrder getWriteOrder() {
+        return writeOrder;
+    }
+
+    public ByteOrder getReadOrder() {
+        return readOrder;
+    }
+
+    public IMessageProtocol getMessageProtocol() {
+        return messageProtocol;
+    }
+
+    public int getMaxWriteBytes() {
+        return maxWriteBytes;
+    }
+
+    public int getMaxReadBytes() {
+        return maxReadBytes;
+    }
+
+    public long getHeartbeatFreq() {
+        return heartbeatFreq;
+    }
+
+    public int getMaxHeartbeatLoseTimes() {
+        return maxHeartbeatLoseTimes;
+    }
+
+    public int getConnectTimeout() {
+        return connectTimeout;
+    }
+
+    public int getMaxResponseDataMb() {
+        return maxResponseDataMb;
+    }
+
+    public AbsReconnection getReconnectionManager() {
+        return reconnectionManager;
+    }
+
+    public SocketSSLConfig getEasySSLConfig() {
+        return easySSLConfig;
+    }
+
+    public SocketFactory getSocketFactory() {
+        return socketFactory;
+    }
+
+    public long getRequestTimeout() {
+        return requestTimeout;
+    }
+
+    public boolean isOpenRequestTimeout() {
+        return isOpenRequestTimeout;
+    }
+
+    public CallbackIDFactory getCallbackIDFactory() {
+        return callbackIDFactory;
+    }
+
+    public static void setIsDebug(boolean isDebug) {
+        EasySocketOptions.isDebug = isDebug;
+    }
+
+    public void setWriteOrder(ByteOrder writeOrder) {
+        this.writeOrder = writeOrder;
+    }
+
+    public void setReadOrder(ByteOrder readOrder) {
+        this.readOrder = readOrder;
+    }
+
+    public void setMessageProtocol(IMessageProtocol messageProtocol) {
+        this.messageProtocol = messageProtocol;
+    }
+
+    public void setMaxWriteBytes(int maxWriteBytes) {
+        this.maxWriteBytes = maxWriteBytes;
+    }
+
+    public void setMaxReadBytes(int maxReadBytes) {
+        this.maxReadBytes = maxReadBytes;
+    }
+
+    public void setHeartbeatFreq(long heartbeatFreq) {
+        this.heartbeatFreq = heartbeatFreq;
+    }
+
+    public void setMaxHeartbeatLoseTimes(int maxHeartbeatLoseTimes) {
+        this.maxHeartbeatLoseTimes = maxHeartbeatLoseTimes;
+    }
+
+    public void setConnectTimeout(int connectTimeout) {
+        this.connectTimeout = connectTimeout;
+    }
+
+    public void setMaxResponseDataMb(int maxResponseDataMb) {
+        this.maxResponseDataMb = maxResponseDataMb;
+    }
+
+    public void setReconnectionManager(AbsReconnection reconnectionManager) {
+        this.reconnectionManager = reconnectionManager;
+    }
+
+    public void setEasySSLConfig(SocketSSLConfig easySSLConfig) {
+        this.easySSLConfig = easySSLConfig;
+    }
+
+    public void setSocketFactory(SocketFactory socketFactory) {
+        this.socketFactory = socketFactory;
+    }
+
+    public void setCallbackIDFactory(CallbackIDFactory callbackIDFactory) {
+        this.callbackIDFactory = callbackIDFactory;
+    }
+
+    public void setRequestTimeout(long requestTimeout) {
+        this.requestTimeout = requestTimeout;
+    }
+
+    public void setOpenRequestTimeout(boolean openRequestTimeout) {
+        isOpenRequestTimeout = openRequestTimeout;
+    }
+
+    public SocketAddress getSocketAddress() {
+        return socketAddress;
+    }
+
+    public SocketAddress getBackupAddress() {
+        return backupAddress;
+    }
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/config/SocketFactory.java b/easysocket/src/main/java/com/easysocket/config/SocketFactory.java
new file mode 100644
index 0000000..1aebab0
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/config/SocketFactory.java
@@ -0,0 +1,14 @@
+package com.easysocket.config;
+
+import com.easysocket.entity.SocketAddress;
+
+import java.net.Socket;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/5/31
+ * Note锛歴ocket宸ュ巶
+ */
+public abstract class SocketFactory {
+    public abstract Socket createSocket(SocketAddress info, EasySocketOptions options) throws Exception;
+}
diff --git a/easysocket/src/main/java/com/easysocket/config/SocketSSLConfig.java b/easysocket/src/main/java/com/easysocket/config/SocketSSLConfig.java
new file mode 100644
index 0000000..1000cce
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/config/SocketSSLConfig.java
@@ -0,0 +1,81 @@
+package com.easysocket.config;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+/**
+ * socket鐨剆sl閰嶇疆
+ */
+
+public class SocketSSLConfig {
+    /**
+     * 瀹夊叏鍗忚鍚嶇О(缂虹渷涓篠SL)
+     */
+    private String mProtocol;
+    /**
+     * 淇′换璇佷功绠$悊鍣�(缂虹渷涓篨509)
+     */
+    private TrustManager[] mTrustManagers;
+    /**
+     * 璇佷功绉橀挜绠$悊鍣�(缂虹渷涓簄ull)
+     */
+    private KeyManager[] mKeyManagers;
+    /**
+     * 鑷畾涔塖SLFactory(缂虹渷涓簄ull)
+     */
+    private SSLSocketFactory mCustomSSLFactory;
+
+    private SocketSSLConfig() {
+
+    }
+
+    public static class Builder {
+
+        private SocketSSLConfig mConfig;
+
+        public Builder() {
+            mConfig = new SocketSSLConfig();
+        }
+
+        public Builder setProtocol(String protocol) {
+            mConfig.mProtocol = protocol;
+            return this;
+        }
+
+        public Builder setTrustManagers(TrustManager[] trustManagers) {
+            mConfig.mTrustManagers = trustManagers;
+            return this;
+        }
+
+        public Builder setKeyManagers(KeyManager[] keyManagers) {
+            mConfig.mKeyManagers = keyManagers;
+            return this;
+        }
+
+        public Builder setCustomSSLFactory(SSLSocketFactory customSSLFactory) {
+            mConfig.mCustomSSLFactory = customSSLFactory;
+            return this;
+        }
+
+        public SocketSSLConfig build() {
+            return mConfig;
+        }
+    }
+
+    public KeyManager[] getKeyManagers() {
+        return mKeyManagers;
+    }
+
+    public String getProtocol() {
+        return mProtocol;
+    }
+
+    public TrustManager[] getTrustManagers() {
+        return mTrustManagers;
+    }
+
+    public SSLSocketFactory getCustomSSLFactory() {
+        return mCustomSSLFactory;
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/action/IOAction.java b/easysocket/src/main/java/com/easysocket/connection/action/IOAction.java
new file mode 100644
index 0000000..4caf13a
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/action/IOAction.java
@@ -0,0 +1,11 @@
+package com.easysocket.connection.action;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/3
+ * Note锛�
+ */
+public interface IOAction {
+    // 鏀跺埌娑堟伅鍝嶅簲
+    String ACTION_READ_COMPLETE = "action_read_complete";
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/action/SocketAction.java b/easysocket/src/main/java/com/easysocket/connection/action/SocketAction.java
new file mode 100644
index 0000000..f9619c8
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/action/SocketAction.java
@@ -0,0 +1,15 @@
+package com.easysocket.connection.action;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛�
+ */
+public interface SocketAction {
+    // 杩炴帴鎴愬姛
+    String ACTION_CONN_SUCCESS="action_conn_success";
+    // 杩炴帴澶辫触
+    String ACTION_CONN_FAIL="action_conn_fail";
+    // 鏂紑杩炴帴
+    String ACTION_DISCONNECTION="action_disconnection";
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/action/SocketStatus.java b/easysocket/src/main/java/com/easysocket/connection/action/SocketStatus.java
new file mode 100644
index 0000000..3918289
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/action/SocketStatus.java
@@ -0,0 +1,17 @@
+package com.easysocket.connection.action;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛氳繛鎺ョ姸鎬�
+ */
+public interface SocketStatus {
+    // 宸叉柇寮�杩炴帴
+    int SOCKET_DISCONNECTED = 0;
+    // 姝e湪杩炴帴
+    int SOCKET_CONNECTING = 1;
+    // 宸茶繛鎺�
+    int SOCKET_CONNECTED = 2;
+    // 姝e湪鏂紑杩炴帴
+    int SOCKET_DISCONNECTING =3;
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/connect/SuperConnection.java b/easysocket/src/main/java/com/easysocket/connection/connect/SuperConnection.java
new file mode 100644
index 0000000..af5491a
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/connect/SuperConnection.java
@@ -0,0 +1,356 @@
+package com.easysocket.connection.connect;
+
+import android.os.Handler;
+
+import com.easysocket.EasySocket;
+import com.easysocket.callback.SuperCallBack;
+import com.easysocket.config.EasySocketOptions;
+import com.easysocket.connection.action.SocketAction;
+import com.easysocket.connection.action.SocketStatus;
+import com.easysocket.connection.dispatcher.CallbackResponseDispatcher;
+import com.easysocket.connection.dispatcher.SocketActionDispatcher;
+import com.easysocket.connection.heartbeat.HeartManager;
+import com.easysocket.connection.iowork.IOManager;
+import com.easysocket.connection.reconnect.AbsReconnection;
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.entity.basemsg.SuperCallbackSender;
+import com.easysocket.exception.NotNullException;
+import com.easysocket.interfaces.config.IConnectionSwitchListener;
+import com.easysocket.interfaces.conn.IConnectionManager;
+import com.easysocket.interfaces.conn.ISocketActionListener;
+import com.easysocket.utils.LogUtil;
+import com.easysocket.utils.Utils;
+
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/5/29
+ * Note锛歴ocket杩炴帴鐨勮秴绫�
+ */
+public abstract class SuperConnection implements IConnectionManager {
+
+    /**
+     * 杩炴帴鐘舵�侊紝鍒濆鍊间负鏂紑杩炴帴
+     */
+    protected final AtomicInteger connectionStatus = new AtomicInteger(SocketStatus.SOCKET_DISCONNECTED);
+    /**
+     * 杩炴帴绾跨▼
+     */
+    private ExecutorService connExecutor;
+    /**
+     * socket鍦板潃淇℃伅
+     */
+    protected SocketAddress socketAddress;
+    /**
+     * socket琛屼负鍒嗗彂鍣�
+     */
+    private SocketActionDispatcher actionDispatcher;
+    /**
+     * 閲嶈繛绠$悊鍣�
+     */
+    private AbsReconnection reconnection;
+    /**
+     * io绠$悊鍣�
+     */
+    private IOManager ioManager;
+    /**
+     * 蹇冭烦绠$悊鍣�
+     */
+    private HeartManager heartManager;
+    /**
+     * 閰嶇疆淇℃伅
+     */
+    protected EasySocketOptions socketOptions;
+    /**
+     * socket鍥炶皟娑堟伅鐨勫垎鍙戝櫒
+     */
+    private CallbackResponseDispatcher callbackResponseDispatcher;
+    /**
+     * 杩炴帴鍒囨崲鐨勭洃鍚�
+     */
+    private IConnectionSwitchListener connectionSwitchListener;
+
+    public SuperConnection(SocketAddress socketAddress) {
+        this.socketAddress = socketAddress;
+        actionDispatcher = new SocketActionDispatcher(this, socketAddress);
+    }
+
+    @Override
+    public void subscribeSocketAction(ISocketActionListener iSocketActionListener) {
+        actionDispatcher.subscribe(iSocketActionListener);
+    }
+
+    @Override
+    public void unSubscribeSocketAction(ISocketActionListener iSocketActionListener) {
+        actionDispatcher.unsubscribe(iSocketActionListener);
+    }
+
+    @Override
+    public synchronized IConnectionManager setOptions(EasySocketOptions socketOptions) {
+        if (socketOptions == null) return this;
+
+        this.socketOptions = socketOptions;
+
+        if (ioManager != null)
+            ioManager.setOptions(socketOptions);
+
+        if (heartManager != null)
+            heartManager.setOptions(socketOptions);
+
+        if (callbackResponseDispatcher != null)
+            callbackResponseDispatcher.setSocketOptions(socketOptions);
+
+        // 鏇存敼浜嗛噸杩炲櫒
+        if (reconnection != null && !reconnection.equals(socketOptions.getReconnectionManager())) {
+            reconnection.detach();
+            reconnection = socketOptions.getReconnectionManager();
+            reconnection.attach(this);
+        }
+        return this;
+    }
+
+    @Override
+    public EasySocketOptions getOptions() {
+        return socketOptions;
+    }
+
+    @Override
+    public synchronized void connect() {
+
+        if (connectionStatus.get() == SocketStatus.SOCKET_DISCONNECTING) {
+            new Handler().postDelayed(new Runnable() {
+                @Override
+                public void run() {
+                    LogUtil.d("---> socket>>connect>>姝e湪鏂紑杩炴帴锛屽欢鏃朵竴绉掑煼琛岄噸杩�");
+                    connect();
+                }
+            }, 1000); // 寤舵椂1绉�
+            return;
+        }
+        LogUtil.d("---> socket寮�濮嬭繛鎺�");
+        if (socketAddress.getIp() == null) {
+            throw new NotNullException("璇锋鏌ユ槸鍚﹁缃簡IP鍦板潃");
+        }
+        // 姝e湪杩炴帴
+        connectionStatus.set(SocketStatus.SOCKET_CONNECTING);
+
+        // 蹇冭烦绠$悊鍣�
+        if (heartManager == null) {
+            heartManager = new HeartManager(this, actionDispatcher);
+        }
+
+        // 閲嶈繛绠$悊鍣�
+        if (reconnection != null) {
+            reconnection.detach();
+        }
+        reconnection = socketOptions.getReconnectionManager();
+        if (reconnection != null) {
+            reconnection.attach(this);
+        }
+
+        // 寮�鍚垎鍙戞秷鎭嚎绋�
+        if (actionDispatcher != null) {
+            actionDispatcher.startDispatchThread();
+        }
+        // 寮�鍚繛鎺ョ嚎绋�
+        if (connExecutor == null || connExecutor.isShutdown()) {
+            // 鏍稿績绾跨▼鏁颁负0锛岄潪鏍稿績绾跨▼鏁板彲浠ユ湁Integer.MAX_VALUE涓紝瀛樻椿鏃堕棿涓�60绉掞紝閫傚悎浜庡湪涓嶆柇杩涜杩炴帴鐨勬儏鍐典笅锛岄伩鍏嶉噸澶嶅垱寤哄拰閿�姣佺嚎绋�
+            connExecutor = Executors.newCachedThreadPool();
+            // 鎵ц杩炴帴浠诲姟
+        }
+        connExecutor.execute(connTask);
+    }
+
+    @Override
+    public synchronized void disconnect(boolean isNeedReconnect) {
+        // 鍒ゆ柇褰撳墠socket鐨勮繛鎺ョ姸鎬�
+        if (connectionStatus.get() == SocketStatus.SOCKET_DISCONNECTED) {
+            return;
+        }
+        // 姝e湪閲嶈繛涓�
+        if (isNeedReconnect && reconnection.isReconning()) {
+            return;
+        }
+        // 姝e湪鏂紑杩炴帴
+        connectionStatus.set(SocketStatus.SOCKET_DISCONNECTING);
+
+        // 寮�鍚柇寮�杩炴帴绾跨▼
+        String info = socketAddress.getIp() + " : " + socketAddress.getPort();
+        Thread disconnThread = new DisconnectThread(isNeedReconnect, "disconn thread锛�" + info);
+        disconnThread.setDaemon(true);
+        disconnThread.start();
+    }
+
+    /**
+     * 鏂紑杩炴帴绾跨▼
+     */
+    private class DisconnectThread extends Thread {
+        boolean isNeedReconnect; // 褰撳墠杩炴帴鐨勬柇寮�鏄惁闇�瑕佽嚜鍔ㄩ噸杩�
+
+        public DisconnectThread(boolean isNeedReconnect, String name) {
+            super(name);
+            this.isNeedReconnect = isNeedReconnect;
+        }
+
+        @Override
+        public void run() {
+            try {
+                // 鍏抽棴io绾跨▼
+                if (ioManager != null)
+                    ioManager.closeIO();
+                // 鍏抽棴鍥炶皟鍒嗗彂鍣ㄧ嚎绋�
+                if (callbackResponseDispatcher != null)
+                    callbackResponseDispatcher.shutdownThread();
+                // 鍏抽棴杩炴帴绾跨▼
+                if (connExecutor != null && !connExecutor.isShutdown()) {
+                    connExecutor.shutdown();
+                    connExecutor = null;
+                }
+                // 鍏抽棴杩炴帴
+                closeConnection();
+                actionDispatcher.dispatchAction(SocketAction.ACTION_DISCONNECTION, new Boolean(isNeedReconnect));
+                if (!isNeedReconnect){
+                    heartManager.stopHeartbeat();
+                }
+                LogUtil.d("---> 鍏抽棴socket杩炴帴");
+                connectionStatus.set(SocketStatus.SOCKET_DISCONNECTED);
+            } catch (IOException e) {
+                // 鏂紑杩炴帴鍙戠敓寮傚父
+                e.printStackTrace();
+            }
+        }
+    }
+
+    // 杩炴帴浠诲姟
+    private Runnable connTask = new Runnable() {
+        @Override
+        public void run() {
+            try {
+                openConnection();
+            } catch (Exception e) {
+                // 杩炴帴寮傚父
+                e.printStackTrace();
+                LogUtil.d("---> socket杩炴帴澶辫触");
+                connectionStatus.set(SocketStatus.SOCKET_DISCONNECTED);
+                // 绗簩涓弬鏁版寚闇�瑕侀噸杩�
+                actionDispatcher.dispatchAction(SocketAction.ACTION_CONN_FAIL, new Boolean(true));
+
+            }
+        }
+    };
+
+    /**
+     * 杩炴帴鎴愬姛
+     */
+    protected void onConnectionOpened() {
+        LogUtil.d("---> socket杩炴帴鎴愬姛");
+        openSocketManager();
+        connectionStatus.set(SocketStatus.SOCKET_CONNECTED);
+        actionDispatcher.dispatchAction(SocketAction.ACTION_CONN_SUCCESS);
+    }
+
+    // 寮�鍚痵ocket鐩稿叧绠$悊鍣�
+    private void openSocketManager() {
+        if (callbackResponseDispatcher == null)
+            callbackResponseDispatcher = new CallbackResponseDispatcher(this);
+        if (ioManager == null) {
+            ioManager = new IOManager(this, actionDispatcher);
+        }
+        ioManager.startIO();
+
+        // 鍚姩鐩稿叧绾跨▼
+        callbackResponseDispatcher.engineThread();
+        ioManager.startIO();
+    }
+
+    // 鍒囨崲浜嗕富鏈篒P鍜岀鍙�
+    @Override
+    public synchronized void switchHost(SocketAddress socketAddress) {
+        if (socketAddress != null) {
+            SocketAddress oldAddress = this.socketAddress;
+            this.socketAddress = socketAddress;
+
+            if (actionDispatcher != null)
+                actionDispatcher.setSocketAddress(socketAddress);
+            // 鍒囨崲涓绘満
+            if (connectionSwitchListener != null) {
+                connectionSwitchListener.onSwitchConnectionInfo(this, oldAddress, socketAddress);
+            }
+        }
+
+    }
+
+    public void setOnConnectionSwitchListener(IConnectionSwitchListener listener) {
+        connectionSwitchListener = listener;
+    }
+
+    @Override
+    public boolean isConnectViable() {
+        // 褰撳墠socket鏄惁澶勪簬鍙繛鎺ョ姸鎬�
+        return Utils.isNetConnected(EasySocket.getInstance().getContext()) && connectionStatus.get() == SocketStatus.SOCKET_DISCONNECTED;
+    }
+
+    @Override
+    public int getConnectionStatus() {
+        return connectionStatus.get();
+    }
+
+    /**
+     * 鎵撳紑杩炴帴
+     *
+     * @throws IOException
+     */
+    protected abstract void openConnection() throws Exception;
+
+    /**
+     * 鍏抽棴杩炴帴
+     *
+     * @throws IOException
+     */
+    protected abstract void closeConnection() throws IOException;
+
+    /**
+     * 鍙戦�乥ytes鏁版嵁
+     *
+     * @param bytes
+     * @return
+     */
+    private IConnectionManager sendBytes(byte[] bytes) {
+        if (ioManager == null || connectionStatus.get() != SocketStatus.SOCKET_CONNECTED) {
+            LogUtil.w("sendBytes閿欒-----ioManager涓簄ull鎴栬�卌onnectionStatus鐘舵�佷笉涓哄凡杩炴帴");
+            return this;
+        }
+        ioManager.sendBytes(bytes);
+        return this;
+    }
+
+    @Override
+    public void onCallBack(SuperCallBack callBack) {
+        callbackResponseDispatcher.addSocketCallback(callBack);
+    }
+
+
+    @Override
+    public synchronized IConnectionManager upBytes(byte[] bytes) {
+        sendBytes(bytes);
+        return this;
+    }
+
+    @Override
+    public synchronized IConnectionManager upCallbackMessage(SuperCallbackSender sender) {
+        callbackResponseDispatcher.checkCallbackSender(sender);
+        // 鍙戦��
+        sendBytes(sender.pack());
+        return this;
+    }
+
+
+    @Override
+    public HeartManager getHeartManager() {
+        return heartManager;
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/connect/TcpConnection.java b/easysocket/src/main/java/com/easysocket/connection/connect/TcpConnection.java
new file mode 100644
index 0000000..c0228b7
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/connect/TcpConnection.java
@@ -0,0 +1,141 @@
+package com.easysocket.connection.connect;
+
+import com.easysocket.config.DefaultX509ProtocolTrustManager;
+import com.easysocket.config.SocketSSLConfig;
+import com.easysocket.connection.action.SocketStatus;
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.utils.LogUtil;
+import com.easysocket.utils.Utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.security.SecureRandom;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/5/29
+ * Note锛歵cp杩炴帴
+ */
+public class TcpConnection extends SuperConnection {
+    /**
+     * socket瀵硅薄
+     */
+    private Socket socket;
+
+    public TcpConnection(SocketAddress socketAddress) {
+        super(socketAddress);
+    }
+
+    @Override
+    protected void openConnection() throws Exception {
+            try {
+                socket = getSocket();
+            } catch (Exception e) {
+                e.printStackTrace();
+                connectionStatus.set(SocketStatus.SOCKET_DISCONNECTED); // 璁剧疆涓烘湭杩炴帴
+                throw new RuntimeException("鍒涘缓socket澶辫触");
+            }
+
+            // 杩涜socket杩炴帴
+            socket.connect(new InetSocketAddress(socketAddress.getIp(), socketAddress.getPort()), socketOptions.getConnectTimeout());
+
+            // 鍏抽棴Nagle绠楁硶,鏃犺TCP鏁版嵁鎶ュぇ灏�,绔嬪嵆鍙戦��
+            socket.setTcpNoDelay(true);
+            // 杩炴帴宸茬粡鎵撳紑
+            if (socket.isConnected() && !socket.isClosed()) {
+                onConnectionOpened();
+            }
+    }
+
+    @Override
+    protected void closeConnection() throws IOException {
+        if (socket != null)
+            socket.close();
+    }
+
+    /**
+     * 鏍规嵁閰嶇疆淇℃伅鑾峰彇瀵瑰簲鐨剆ocket
+     *
+     * @return
+     */
+    private synchronized Socket getSocket() throws Exception {
+        // 鑷畾涔夌殑socket鐢熸垚宸ュ巶
+        if (socketOptions.getSocketFactory() != null) {
+            return socketOptions.getSocketFactory().createSocket(socketAddress, socketOptions);
+        }
+        // 榛樿鎿嶄綔
+        SocketSSLConfig config = socketOptions.getEasySSLConfig();
+        if (config == null) {
+            return new Socket();
+        }
+        // 鑾峰彇SSL閰嶇疆宸ュ巶
+        SSLSocketFactory factory = config.getCustomSSLFactory();
+        if (factory == null) {
+            String protocol = "SSL";
+            if (!Utils.isStringEmpty(config.getProtocol())) {
+                protocol = config.getProtocol();
+            }
+
+            TrustManager[] trustManagers = config.getTrustManagers();
+            if (trustManagers == null || trustManagers.length == 0) {
+                // 缂虹渷淇′换鎵�鏈夎瘉涔�
+                trustManagers = new TrustManager[]{new DefaultX509ProtocolTrustManager()};
+            }
+
+            try {
+                SSLContext sslContext = SSLContext.getInstance(protocol);
+                sslContext.init(config.getKeyManagers(), trustManagers, new SecureRandom());
+                return sslContext.getSocketFactory().createSocket();
+            } catch (Exception e) {
+                if (socketOptions.isDebug()) {
+                    e.printStackTrace();
+                }
+                LogUtil.e(e.getMessage());
+                return new Socket();
+            }
+
+        } else {
+            try {
+                return factory.createSocket();
+            } catch (IOException e) {
+                if (socketOptions.isDebug()) {
+                    e.printStackTrace();
+                }
+                LogUtil.e(e.getMessage());
+                return new Socket();
+            }
+        }
+    }
+
+
+    @Override
+    public InputStream getInputStream() {
+        if (socket != null && socket.isConnected() && !socket.isClosed()) {
+            try {
+                return socket.getInputStream();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public OutputStream getOutStream() {
+        if (socket != null && socket.isConnected() && !socket.isClosed()) {
+            try {
+                return socket.getOutputStream();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/dispatcher/CallbackResponseDispatcher.java b/easysocket/src/main/java/com/easysocket/connection/dispatcher/CallbackResponseDispatcher.java
new file mode 100644
index 0000000..dc0d4e6
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/dispatcher/CallbackResponseDispatcher.java
@@ -0,0 +1,191 @@
+package com.easysocket.connection.dispatcher;
+
+import com.easysocket.callback.SuperCallBack;
+import com.easysocket.config.EasySocketOptions;
+import com.easysocket.entity.OriginReadData;
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.entity.basemsg.SuperCallbackSender;
+import com.easysocket.exception.RequestTimeOutException;
+import com.easysocket.interfaces.conn.IConnectionManager;
+import com.easysocket.interfaces.conn.SocketActionListener;
+import com.easysocket.utils.LogUtil;
+import com.easysocket.utils.Utils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/4
+ * Note锛氬洖璋冩秷鎭垎鍙戝櫒
+ */
+public class CallbackResponseDispatcher {
+    /**
+     * 淇濆瓨鍙戦�佺殑姣忎釜鍥炶皟娑堟伅鐨勭洃鍚疄渚嬶紝key涓哄洖璋冩爣璇哻allbackId锛岃繖鏍峰洖璋冩秷鎭湁鍙嶉鐨勬椂鍊欙紝灏卞彲浠ユ壘鍒板苟璋冪敤
+     * 瀵瑰簲鐨勭洃鍚璞�
+     */
+    private Map<String, SuperCallBack> callbacks = new HashMap<>();
+    /**
+     * 淇濆瓨闇�瑕佽繘琛岃秴鏃舵娴嬬殑璇锋眰锛岃繖鏄竴涓欢鏃堕槦鍒楋紝鍏冪礌瓒呮椂鐨勬椂鍊欎細琚彇鍑烘潵
+     */
+    private DelayQueue<timeoutItem> timeoutQueue = new DelayQueue<>();
+    /**
+     * 瓒呮椂妫�娴嬬殑绾跨▼绠$悊鍣�
+     */
+    private ExecutorService timeoutExecutor;
+
+    /**
+     * 杩炴帴绠$悊
+     */
+    IConnectionManager connectionManager;
+
+    private EasySocketOptions socketOptions;
+
+
+    public CallbackResponseDispatcher(IConnectionManager connectionManager) {
+        this.connectionManager = connectionManager;
+        socketOptions = connectionManager.getOptions();
+        // 娉ㄥ唽鐩戝惉
+        connectionManager.subscribeSocketAction(socketActionListener);
+        // 寮�濮嬭秴鏃舵娴嬬嚎绋�
+        engineThread();
+    }
+
+    /**
+     * 璁剧疆socketoptions
+     *
+     * @param socketOptions
+     */
+    public void setSocketOptions(EasySocketOptions socketOptions) {
+        this.socketOptions = socketOptions;
+    }
+
+    /**
+     * 瓒呮椂妫�娴嬬嚎绋�
+     */
+    public void engineThread() {
+        try {
+            if (timeoutExecutor == null || timeoutExecutor.isShutdown()) {
+                timeoutExecutor = Executors.newSingleThreadExecutor();
+                timeoutExecutor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            // 鍙湁瓒呮椂鐨勫厓绱犳墠浼氳鍙栧嚭锛屾病鏈夌殑璇濅細琚瓑寰�
+                            timeoutItem item = timeoutQueue.take();
+                            if (item != null) {
+                                SuperCallBack callBack = callbacks.remove(item.callbackId);
+                                if (callBack != null)
+                                    callBack.onError(new RequestTimeOutException("request timeout"));
+                            }
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                        // 缁х画寰幆
+                        if (timeoutExecutor != null && !timeoutExecutor.isShutdown()) {
+                            run();
+                        }
+                    }
+                });
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 鍏抽棴绾跨▼
+     */
+    public void shutdownThread() {
+        if (timeoutExecutor != null && !timeoutExecutor.isShutdown()) {
+            // shutdown鍜宻hutdownNow鐨勪富瑕佸尯鍒槸鍓嶈�呬腑鏂湭鎵ц鐨勭嚎绋嬶紝鍚庤�呬腑鏂墍鏈夌嚎绋�
+            timeoutExecutor.shutdownNow();
+            timeoutExecutor = null;
+        }
+
+    }
+
+    /**
+     * socket琛屼负鐩戝惉锛岄噸鍐欏弽棣堟秷鎭殑鍥炶皟鏂规硶
+     */
+    private SocketActionListener socketActionListener = new SocketActionListener() {
+        @Override
+        public void onSocketResponse(SocketAddress socketAddress, OriginReadData originReadData) {
+            if (callbacks.size() == 0) return;
+            if (socketOptions.getCallbackIDFactory() == null) return;
+            // 鑾峰彇鍥炶皟ID
+            String callbackID = socketOptions.getCallbackIDFactory().getCallbackID(originReadData);
+            if (callbackID != null) {
+                // 鑾峰彇callbackID瀵瑰簲鐨刢allback
+                SuperCallBack callBack = callbacks.get(callbackID);
+                if (callBack != null) {
+                    // 鍥炶皟
+                    callBack.onSuccess(originReadData);
+                    callbacks.remove(callbackID); // 绉婚櫎瀹屾垚浠诲姟鐨刢allback
+                    LogUtil.d("绉婚櫎鐨刢allbackId-->" + callbackID);
+                }
+            }
+        }
+    };
+
+
+    /**
+     * 姣忓彂涓�鏉″洖璋冩秷鎭兘瑕佸湪杩欓噷娣诲姞鐩戝惉瀵硅薄
+     *
+     * @param superCallBack
+     */
+    public void addSocketCallback(SuperCallBack superCallBack) {
+        callbacks.put(superCallBack.getCallbackId(), superCallBack);
+        // 鏀惧叆寤舵椂闃熷垪
+        long delayTime = socketOptions == null ?
+                EasySocketOptions.getDefaultOptions().getRequestTimeout() : socketOptions.getRequestTimeout();
+        timeoutQueue.add(new timeoutItem(superCallBack.getCallbackId(), delayTime, TimeUnit.MILLISECONDS));
+    }
+
+    /**
+     * 寤舵椂闃熷垪鐨刬tem
+     */
+    class timeoutItem implements Delayed {
+
+        String callbackId; // 褰撳墠callback鐨刢allbackId
+        long executeTime; // 瑙﹀彂鏃堕棿
+
+        public timeoutItem(String callbackId, long delayTime, TimeUnit timeUnit) {
+            this.callbackId = callbackId;
+            this.executeTime = System.currentTimeMillis() + (delayTime > 0 ? timeUnit.toMillis(delayTime) : 0);
+        }
+
+        @Override
+        public long getDelay(TimeUnit unit) {
+            return executeTime - System.currentTimeMillis();
+        }
+
+        @Override
+        public int compareTo(Delayed o) {
+            return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
+        }
+    }
+
+    /**
+     * 鍚屼竴涓秷鎭彂閫佸娆★紝callbackId鏄笉鑳戒竴鏍风殑锛屾墍浠ヨ繖閲岃鍏坈heck涓�涓嬶紝鍚﹀垯鏈嶅姟绔弽棣堢殑鏃跺�欙紝瀹㈡埛绔帴鏀跺氨浼氫贡濂�
+     *
+     * @param callbackSender
+     * @return
+     */
+    public void checkCallbackSender(SuperCallbackSender callbackSender) {
+
+        Utils.checkNotNull(socketOptions.getCallbackIDFactory(), "瑕佹兂瀹炵幇EasySocket鐨勫洖璋冨姛鑳斤紝CallbackIdFactory涓嶈兘涓簄ull锛�" +
+                "璇峰疄鐜颁竴涓狢allbackIdFactory骞跺湪鍒濆鍖栫殑鏃跺�欓�氳繃EasySocketOptions鐨剆etCallbackIdFactory杩涜閰嶇疆");
+        String callbackId = callbackSender.getCallbackId();
+        // 鍚屼竴涓秷鎭彂閫佷袱娆′互涓婏紝callbackId鏄笉鑳戒竴鏍风殑锛屽惁鍒欐湇鍔$鍙嶉鐨勬椂鍊欙紝瀹㈡埛绔帴鏀跺氨浼氫贡濂�
+        if (callbacks.containsKey(callbackId)) {
+            callbackSender.generateCallbackId();
+        }
+    }
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/dispatcher/MainThreadExecutor.java b/easysocket/src/main/java/com/easysocket/connection/dispatcher/MainThreadExecutor.java
new file mode 100644
index 0000000..37e8579
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/dispatcher/MainThreadExecutor.java
@@ -0,0 +1,21 @@
+package com.easysocket.connection.dispatcher;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Author锛歁apogo
+ * Date锛�2020/4/8
+ * Note锛氬垏鍒颁富绾跨▼
+ */
+public class MainThreadExecutor implements Executor {
+
+    private final Handler handler = new Handler(Looper.getMainLooper());
+
+    @Override
+    public void execute(Runnable r) {
+        handler.post(r);
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/dispatcher/SocketActionDispatcher.java b/easysocket/src/main/java/com/easysocket/connection/dispatcher/SocketActionDispatcher.java
new file mode 100644
index 0000000..f0a61cf
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/dispatcher/SocketActionDispatcher.java
@@ -0,0 +1,221 @@
+package com.easysocket.connection.dispatcher;
+
+import com.easysocket.EasySocket;
+import com.easysocket.entity.OriginReadData;
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.interfaces.conn.IConnectionManager;
+import com.easysocket.interfaces.conn.ISocketActionDispatch;
+import com.easysocket.interfaces.conn.ISocketActionListener;
+import com.easysocket.utils.Utils;
+
+import java.io.Serializable;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import static com.easysocket.connection.action.IOAction.ACTION_READ_COMPLETE;
+import static com.easysocket.connection.action.SocketAction.ACTION_CONN_FAIL;
+import static com.easysocket.connection.action.SocketAction.ACTION_CONN_SUCCESS;
+import static com.easysocket.connection.action.SocketAction.ACTION_DISCONNECTION;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛歴ocket琛屼负鍒嗗彂鍣�
+ */
+public class SocketActionDispatcher implements ISocketActionDispatch {
+    /**
+     * 杩炴帴鍦板潃
+     */
+    private SocketAddress socketAddress;
+    /**
+     * 杩炴帴鍣�
+     */
+    private IConnectionManager connectionManager;
+    /**
+     * 鍥炶皟鐩戝惉闆嗗悎
+     */
+    private List<ISocketActionListener> actionListeners = new ArrayList<>();
+    /**
+     * 澶勭悊socket琛屼负鐨勭嚎绋�
+     */
+    private Thread actionThread;
+    /**
+     * 鏄惁鍋滄鍒嗗彂
+     */
+    private boolean isStop;
+
+    /**
+     * 浜嬩欢娑堣垂闃熷垪
+     */
+    private final LinkedBlockingQueue<ActionBean> socketActions = new LinkedBlockingQueue();
+    /**
+     * 鍒囨崲鍒癠I绾跨▼
+     */
+    private MainThreadExecutor mainThreadExecutor = new MainThreadExecutor();
+
+
+    public SocketActionDispatcher(IConnectionManager connectionManager, SocketAddress socketAddress) {
+        this.socketAddress = socketAddress;
+        this.connectionManager = connectionManager;
+    }
+
+    public void setSocketAddress(SocketAddress info) {
+        socketAddress = info;
+    }
+
+
+    @Override
+    public void dispatchAction(String action) {
+        dispatchAction(action, null);
+    }
+
+    @Override
+    public void dispatchAction(String action, Serializable serializable) {
+        // 灏嗘帴鏀跺埌鐨剆ocket琛屼负灏佽鍏ュ垪
+        ActionBean actionBean = new ActionBean(action, serializable, this);
+        socketActions.offer(actionBean);
+    }
+
+    @Override
+    public void subscribe(ISocketActionListener iSocketActionListener) {
+        if (iSocketActionListener != null && !actionListeners.contains(iSocketActionListener)) {
+            actionListeners.add(iSocketActionListener);
+        }
+    }
+
+    @Override
+    public void unsubscribe(ISocketActionListener iSocketActionListener) {
+        actionListeners.remove(iSocketActionListener);
+    }
+
+    /**
+     * 鍒嗗彂绾跨▼
+     */
+    private class DispatchThread extends Thread {
+
+        public DispatchThread() {
+            super("dispatch thread");
+        }
+
+        @Override
+        public void run() {
+            // 寰幆澶勭悊socket鐨勮涓轰俊鎭�
+            while (!isStop) {
+                try {
+                    ActionBean actionBean = socketActions.take();
+                    if (actionBean != null && actionBean.mDispatcher != null) {
+                        SocketActionDispatcher actionDispatcher = actionBean.mDispatcher;
+                        List<ISocketActionListener> copyListeners = new ArrayList<>(actionDispatcher.actionListeners);
+                        Iterator<ISocketActionListener> listeners = copyListeners.iterator();
+                        // 閫氱煡鎵�鏈夌洃鍚��
+                        while (listeners.hasNext()) {
+                            ISocketActionListener listener = listeners.next();
+                            actionDispatcher.dispatchActionToListener(actionBean.mAction, actionBean.arg, listener);
+                        }
+                    }
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     * socket琛屼负鐨勫皝瑁�
+     */
+    protected static class ActionBean {
+
+        public ActionBean(String action, Serializable arg, SocketActionDispatcher dispatcher) {
+            mAction = action;
+            this.arg = arg;
+            mDispatcher = dispatcher;
+        }
+
+        String mAction = "";
+        Serializable arg;
+        SocketActionDispatcher mDispatcher;
+    }
+
+    /**
+     * 鍒嗗彂琛屼负缁欑洃鍚��
+     *
+     * @param action
+     * @param content
+     * @param actionListener
+     */
+    private void dispatchActionToListener(String action, final Serializable content, final ISocketActionListener actionListener) {
+        switch (action) {
+
+            case ACTION_CONN_SUCCESS: // 杩炴帴鎴愬姛
+                mainThreadExecutor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        actionListener.onSocketConnSuccess(socketAddress);
+                    }
+                });
+
+                break;
+
+            case ACTION_CONN_FAIL: // 杩炴帴澶辫触
+                mainThreadExecutor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        actionListener.onSocketConnFail(socketAddress, ((Boolean) content).booleanValue());
+                    }
+                });
+
+                break;
+
+            case ACTION_DISCONNECTION: // 杩炴帴鏂紑
+                mainThreadExecutor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        actionListener.onSocketDisconnect(socketAddress, ((Boolean) content).booleanValue());
+                        // 涓嶉渶瑕侀噸杩烇紝鍒欓噴鏀捐祫婧�
+                        if (!(Boolean) content) {
+                            stopDispatchThread();
+                        }
+                    }
+                });
+                break;
+
+            case ACTION_READ_COMPLETE: // 璇诲彇鏁版嵁瀹屾垚
+                mainThreadExecutor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        // response鏈変笁绉嶅舰寮�
+                        actionListener.onSocketResponse(socketAddress, (OriginReadData) content);
+                        byte[] data = Utils.concatBytes(((OriginReadData) content).getHeaderData(), ((OriginReadData) content).getBodyBytes());
+                        actionListener.onSocketResponse(socketAddress, new String(data, Charset.forName(EasySocket.getInstance().getDefOptions().getCharsetName())));
+                        actionListener.onSocketResponse(socketAddress, data);
+                    }
+                });
+                break;
+        }
+    }
+
+    // 寮�濮嬪垎鍙戠嚎绋�
+    @Override
+    public void startDispatchThread() {
+        isStop = false;
+        if (actionThread == null) {
+            actionThread = new DispatchThread();
+            actionThread.start();
+        }
+    }
+
+    @Override
+    public void stopDispatchThread() {
+        if (actionThread != null && actionThread.isAlive() && !actionThread.isInterrupted()) {
+            socketActions.clear();
+            //actionListeners.clear();
+            isStop = true;
+            actionThread.interrupt();
+            actionThread = null;
+        }
+    }
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/heartbeat/HeartManager.java b/easysocket/src/main/java/com/easysocket/connection/heartbeat/HeartManager.java
new file mode 100644
index 0000000..9ae8042
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/heartbeat/HeartManager.java
@@ -0,0 +1,181 @@
+package com.easysocket.connection.heartbeat;
+
+import com.easysocket.config.EasySocketOptions;
+import com.easysocket.entity.OriginReadData;
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.interfaces.config.IOptions;
+import com.easysocket.interfaces.conn.IConnectionManager;
+import com.easysocket.interfaces.conn.IHeartManager;
+import com.easysocket.interfaces.conn.ISocketActionDispatch;
+import com.easysocket.interfaces.conn.SocketActionListener;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/12/8
+ * Note锛氬績璺冲寘妫�娴嬬鐞嗗櫒
+ */
+public class HeartManager extends SocketActionListener implements IOptions, IHeartManager {
+
+    /**
+     * 杩炴帴鍣�
+     */
+    private IConnectionManager connectionManager;
+    /**
+     * 杩炴帴鍙傛暟
+     */
+    private EasySocketOptions socketOptions;
+    /**
+     * 瀹㈡埛绔績璺冲寘
+     */
+    private byte[] clientHeart;
+    /**
+     * 蹇冭烦鍖呭彂閫佺嚎绋�
+     */
+    private ScheduledExecutorService heartExecutor;
+    /**
+     * 璁板綍蹇冭烦鐨勫け鑱旀鏁�
+     */
+    private AtomicInteger loseTimes = new AtomicInteger(-1);
+    /**
+     * 蹇冭烦棰戠巼
+     */
+    private long freq;
+    /**
+     * 鏄惁婵�娲讳簡蹇冭烦
+     */
+    private boolean isActivate;
+
+
+    /**
+     * 蹇冭烦鍖呮帴鏀剁洃鍚�
+     */
+    private HeartbeatListener heartbeatListener;
+
+
+    public HeartManager(IConnectionManager iConnectionManager, ISocketActionDispatch actionDispatch) {
+        this.connectionManager = iConnectionManager;
+        socketOptions = iConnectionManager.getOptions();
+        actionDispatch.subscribe(this); // 娉ㄥ唽鐩戝惉
+    }
+
+    /**
+     * 蹇冭烦鍙戦�佷换鍔�
+     */
+    private final Runnable beatTask = new Runnable() {
+        @Override
+        public void run() {
+            // 蹇冭烦涓㈠け娆℃暟鍒ゆ柇锛屽績璺冲寘涓㈠け浜嗕竴瀹氱殑娆℃暟鍒欎細杩涜socket鐨勬柇寮�閲嶈繛
+            if (socketOptions.getMaxHeartbeatLoseTimes() != -1
+                    && loseTimes.incrementAndGet() >= socketOptions.getMaxHeartbeatLoseTimes()) {
+                // 鏂紑閲嶈繛
+                connectionManager.disconnect(true);
+                resetLoseTimes();
+            } else { // 鍙戦�佸績璺冲寘
+                connectionManager.upBytes(clientHeart);
+            }
+        }
+    };
+
+
+    @Override
+    public void startHeartbeat(byte[] clientHeart, HeartbeatListener listener) {
+        this.clientHeart = clientHeart;
+        this.heartbeatListener = listener;
+        isActivate = true;
+        openThread();
+    }
+
+
+    // 鍚姩蹇冭烦绾跨▼
+    private void openThread() {
+        freq = socketOptions.getHeartbeatFreq(); // 蹇冭烦棰戠巼
+        //  鍚姩绾跨▼鍙戦�佸績璺�
+        if (heartExecutor == null || heartExecutor.isShutdown()) {
+            heartExecutor = Executors.newSingleThreadScheduledExecutor();
+            heartExecutor.scheduleWithFixedDelay(beatTask, 0, freq, TimeUnit.MILLISECONDS);
+        }
+    }
+
+    /**
+     * 鍋滄蹇冭烦鍙戦��
+     */
+    @Override
+    public void stopHeartbeat() {
+        isActivate = false;
+        closeThread();
+    }
+
+    // 鍋滄蹇冭烦绾跨▼
+    private void closeThread() {
+        if (heartExecutor != null && !heartExecutor.isShutdown()) {
+            heartExecutor.shutdownNow();
+            heartExecutor = null;
+            resetLoseTimes(); // 閲嶇疆
+        }
+    }
+
+    @Override
+    public void onReceiveHeartBeat() {
+        resetLoseTimes();
+    }
+
+
+    private void resetLoseTimes() {
+        loseTimes.set(-1);
+    }
+
+    @Override
+    public void onSocketConnSuccess(SocketAddress socketAddress) {
+        if (isActivate) {
+            openThread();
+        }
+    }
+
+    @Override
+    public void onSocketConnFail(SocketAddress socketAddress, boolean isNeedReconnect) {
+        // 濡傛灉涓嶉渶瑕侀噸杩烇紝鍒欏仠姝㈠績璺抽鐜囩嚎绋�
+        if (!isNeedReconnect) {
+            closeThread();
+        }
+    }
+
+    @Override
+    public void onSocketDisconnect(SocketAddress socketAddress, boolean isNeedReconnect) {
+        // 濡傛灉涓嶉渶瑕侀噸杩烇紝鍒欏仠姝㈠績璺虫娴�
+        if (!isNeedReconnect) {
+            closeThread();
+        }
+    }
+
+    @Override
+    public void onSocketResponse(SocketAddress socketAddress, OriginReadData originReadData) {
+        if (heartbeatListener != null && heartbeatListener.isServerHeartbeat(originReadData)) {
+            // 鏀跺埌鏈嶅姟鍣ㄥ績璺�
+            onReceiveHeartBeat();
+        }
+    }
+
+    @Override
+    public Object setOptions(EasySocketOptions socketOptions) {
+        this.socketOptions = socketOptions;
+        freq = socketOptions.getHeartbeatFreq();
+        freq = freq < 1000 ? 1000 : freq; // 涓嶈兘灏忎簬涓�绉�
+        return this;
+    }
+
+    @Override
+    public EasySocketOptions getOptions() {
+        return socketOptions;
+    }
+
+    public interface HeartbeatListener {
+        // 鏄惁涓烘湇鍔″櫒蹇冭烦
+        boolean isServerHeartbeat(OriginReadData orginReadData);
+    }
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/iowork/EasyReader.java b/easysocket/src/main/java/com/easysocket/connection/iowork/EasyReader.java
new file mode 100644
index 0000000..d2bea0d
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/iowork/EasyReader.java
@@ -0,0 +1,337 @@
+package com.easysocket.connection.iowork;
+
+import com.easysocket.config.EasySocketOptions;
+import com.easysocket.connection.action.IOAction;
+import com.easysocket.connection.action.SocketStatus;
+import com.easysocket.entity.OriginReadData;
+import com.easysocket.exception.ReadRecoverableExeption;
+import com.easysocket.exception.ReadUnrecoverableException;
+import com.easysocket.interfaces.config.IMessageProtocol;
+import com.easysocket.interfaces.conn.IConnectionManager;
+import com.easysocket.interfaces.conn.ISocketActionDispatch;
+import com.easysocket.interfaces.io.IReader;
+import com.easysocket.utils.HexUtil;
+import com.easysocket.utils.LogUtil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛�
+ */
+public class EasyReader implements IReader<EasySocketOptions> {
+    /**
+     * 杈撳叆娴�
+     */
+    private InputStream inputStream;
+    /**
+     * 璇诲彇鍘熷鏁版嵁鐨勭紦瀛樼┖闂�
+     */
+    private ByteBuffer originBuf;
+    /**
+     * socket琛屼负鍒嗗彂鍣�
+     */
+    private ISocketActionDispatch actionDispatch;
+    /**
+     * 杩炴帴鍣�
+     */
+    private IConnectionManager connectionManager;
+    /**
+     * 杩炴帴鍙傛暟
+     */
+    private EasySocketOptions socketOptions;
+
+    /**
+     * 璇绘暟鎹椂锛屼綑鐣欐暟鎹殑缂撳瓨
+     */
+    private ByteBuffer remainingBuf;
+    /**
+     * 璇绘暟鎹嚎绋�
+     */
+    private Thread readerThread;
+    /**
+     * 鏄惁鍋滄绾跨▼
+     */
+    private boolean stopThread;
+
+    public EasyReader(IConnectionManager connectionManager, ISocketActionDispatch actionDispatch) {
+        this.actionDispatch = actionDispatch;
+        this.connectionManager = connectionManager;
+        socketOptions = connectionManager.getOptions();
+    }
+
+    @Override
+    public void read() throws IOException, ReadRecoverableExeption, ReadUnrecoverableException {
+        OriginReadData originalData = new OriginReadData();
+        IMessageProtocol messageProtocol = socketOptions.getMessageProtocol();
+        // 娑堟伅鍗忚涓簄ull锛屽垯鐩存帴璇诲師濮嬫秷鎭紝涓嶅缓璁繖鏍蜂娇鐢紝鍥犱负浼氬彂鐢熼粡鍖呫�佸垎鍖呯殑闂
+        if (messageProtocol == null) {
+            readOriginDataFromSteam(originalData);
+            return;
+        }
+
+        // 瀹氫箟浜嗘秷鎭崗璁�
+        int headerLength = messageProtocol.getHeaderLength(); // 鍖呭ご闀垮害
+        ByteBuffer headBuf = ByteBuffer.allocate(headerLength); // 鍖呭ご鏁版嵁鐨刡uffer
+        headBuf.order(socketOptions.getReadOrder());
+
+        /*1銆佽 header=====>>>*/
+        if (remainingBuf != null) { // 鏈変綑鐣�
+            // flip鏂规硶锛氫竴鑸粠Buffer璇绘暟鎹墠璋冪敤锛屽皢limit璁剧疆涓哄綋鍓峱osition锛屽皢position璁剧疆涓�0锛屽湪璇绘暟鎹椂锛宭imit浠h〃鍙鏁版嵁鐨勬湁鏁堥暱搴�
+            remainingBuf.flip();
+            // 璇讳綑鐣欐暟鎹殑闀垮害
+            int length = Math.min(remainingBuf.remaining(), headerLength);
+            // 璇诲叆浣欑暀鏁版嵁
+            headBuf.put(remainingBuf.array(), 0, length);
+
+            if (length < headerLength) { // 浣欑暀鏁版嵁灏忎簬涓�涓猦eader
+                // there are no data left
+                remainingBuf = null;
+                // 浠巗tream涓鍓╀笅鐨刪eader鏁版嵁
+                readHeaderFromSteam(headBuf, headerLength - length);
+            } else {
+                // 绉诲姩寮�濮嬭鏁版嵁鐨勬寚閽�
+                remainingBuf.position(headerLength);
+            }
+        } else { // 鏃犱綑鐣�
+            // 浠巗tream璇诲彇涓�涓畬鏁寸殑 header
+            readHeaderFromSteam(headBuf, headBuf.capacity());
+        }
+
+        // 淇濆瓨header
+        originalData.setHeaderData(headBuf.array());
+
+        /*2銆佽 body=====>>>*/
+        int bodyLength = messageProtocol.getBodyLength(originalData.getHeaderData(), socketOptions.getReadOrder());
+        if (bodyLength > 0) {
+            if (bodyLength > socketOptions.getMaxResponseDataMb() * 1024 * 1024) {
+                throw new ReadUnrecoverableException("鏈嶅姟鍣ㄨ繑鍥炵殑鍗曟鏁版嵁瓒呰繃浜嗚瀹氱殑鏈�澶у�硷紝鍙兘浣犵殑Socket娑堟伅鍗忚涓嶅锛屼竴鑸秷鎭牸寮�" +
+                        "涓猴細Header+Body锛屽叾涓璈eader淇濆瓨娑堟伅闀垮害鍜岀被鍨嬬瓑锛孊ody淇濆瓨娑堟伅鍐呭锛岃瑙勮寖濂戒綘鐨勫崗璁�");
+            }
+            // 鍒嗛厤绌洪棿
+            ByteBuffer bodyBuf = ByteBuffer.allocate(bodyLength);
+            bodyBuf.order(socketOptions.getReadOrder());
+
+            // 鏈変綑鐣�
+            if (remainingBuf != null) {
+                int bodyStartPosition = remainingBuf.position();
+
+                int length = Math.min(remainingBuf.remaining(), bodyLength);
+                // 璇籰ength澶у皬鐨勪綑鐣欐暟鎹�
+                bodyBuf.put(remainingBuf.array(), bodyStartPosition, length);
+                // 绉诲姩position浣嶇疆
+                remainingBuf.position(bodyStartPosition + length);
+
+                // 璇荤殑浣欑暀鏁版嵁鍒氬ソ绛変簬涓�涓猙ody
+                if (length == bodyLength) {
+                    if (remainingBuf.remaining() > 0) { // 浣欑暀鏁版嵁鏈瀹�
+                        ByteBuffer temp = ByteBuffer.allocate(remainingBuf.remaining());
+                        temp.order(socketOptions.getReadOrder());
+                        temp.put(remainingBuf.array(), remainingBuf.position(), remainingBuf.remaining());
+                        remainingBuf = temp;
+                    } else { // there are no data left
+                        remainingBuf = null;
+                    }
+
+                    // 淇濆瓨body
+                    originalData.setBodyData(bodyBuf.array());
+
+                    LogUtil.d("Socket鏀跺埌鏁版嵁-->" +HexUtil.bytesToHex(originalData.getBodyBytes()) );
+                    // 鍒嗗彂鏁版嵁
+                    actionDispatch.dispatchAction(IOAction.ACTION_READ_COMPLETE, originalData);
+
+                    /*return璇诲彇缁撴潫*/
+                    return;
+
+                } else { // there are no data left in buffer and some data pieces in channel
+                    remainingBuf = null;
+                }
+            }
+            // 鏃犱綑鐣欙紝鍒欎粠stream涓
+            readBodyFromStream(bodyBuf);
+            // 淇濆瓨body鍒皁riginalData
+            originalData.setBodyData(bodyBuf.array());
+
+        } else if (bodyLength == 0) { // 娌℃湁body鏁版嵁
+            originalData.setBodyData(new byte[0]);
+            if (remainingBuf != null) {
+                // the body is empty so header remaining buf need set null
+                if (remainingBuf.hasRemaining()) {
+                    ByteBuffer temp = ByteBuffer.allocate(remainingBuf.remaining());
+                    temp.order(socketOptions.getReadOrder());
+                    temp.put(remainingBuf.array(), remainingBuf.position(), remainingBuf.remaining());
+                    remainingBuf = temp;
+                } else {
+                    remainingBuf = null;
+                }
+            }
+        } else if (bodyLength < 0) {
+            throw new ReadUnrecoverableException("鏁版嵁body鐨勯暱搴︿笉鑳藉皬浜�0");
+        }
+
+        LogUtil.d("Socket鏀跺埌鏁版嵁-->" + HexUtil.bytesToHex(originalData.getBodyBytes()));
+        // 鍒嗗彂
+        actionDispatch.dispatchAction(IOAction.ACTION_READ_COMPLETE, originalData);
+
+    }
+
+
+    /**
+     * 璇绘暟鎹换鍔�
+     */
+    private Runnable readerTask = new Runnable() {
+        @Override
+        public void run() {
+            try {
+                while (!stopThread) {
+                    read();
+                }
+            } catch (ReadUnrecoverableException unrecoverableException) {
+                // 璇诲紓甯�
+                unrecoverableException.printStackTrace();
+                // 鍋滄绾跨▼
+                stopThread = true;
+                release();
+            } catch (ReadRecoverableExeption readRecoverableExeption) {
+                readRecoverableExeption.printStackTrace();
+                // 閲嶈繛
+                LogUtil.d("--->閲嶈繛 ReadRecoverableExeption");
+                connectionManager.disconnect(true);
+
+            } catch (IOException e) {
+                e.printStackTrace();
+                // 閲嶈繛
+                LogUtil.d("--->閲嶈繛 IOException");
+                if (connectionManager.getConnectionStatus() != SocketStatus.SOCKET_DISCONNECTING) {
+                    connectionManager.disconnect(true);
+                }
+            }
+        }
+    };
+
+
+    private void readHeaderFromSteam(ByteBuffer headBuf, int readLength) throws ReadRecoverableExeption, IOException {
+        for (int i = 0; i < readLength; i++) {
+            byte[] bytes = new byte[1];
+            // 浠庤緭鍏ユ祦涓鏁版嵁锛屾棤鏁版嵁鏃朵細闃诲
+            int value = inputStream.read(bytes);
+            // -1浠h〃璇诲埌浜嗘枃浠剁殑鏈熬锛屼竴鑸槸鍥犱负鏈嶅姟鍣ㄦ柇寮�浜嗚繛鎺�
+            if (value == -1) {
+                throw new ReadRecoverableExeption("璇绘暟鎹け璐ワ紝鍙兘鏄洜涓簊ocket璺熸湇鍔″櫒鏂紑浜嗚繛鎺�");
+            }
+            headBuf.put(bytes);
+        }
+    }
+
+    private void readOriginDataFromSteam(OriginReadData readData) throws ReadRecoverableExeption, IOException {
+        // 鐢� 鍏ㄥ眬originBuf閬垮厤閲嶅鍒涘缓瀛楄妭鏁扮粍
+        int len = inputStream.read(originBuf.array());
+        // no more data
+        if (len == -1) {
+            throw new ReadRecoverableExeption("璇绘暟鎹け璐ワ紝鍙兘鍥犱负socket璺熸湇鍔″櫒鏂紑浜嗚繛鎺�");
+        }
+        // bytes澶嶅埗
+        byte[] data = new byte[len];
+        originBuf.get(data, 0, len);
+        readData.setBodyData(data);
+        LogUtil.d("Socket鏀跺埌鏁版嵁-->" + HexUtil.bytesToHex(readData.getBodyBytes()));
+        // 鍒嗗彂鏁版嵁
+        actionDispatch.dispatchAction(IOAction.ACTION_READ_COMPLETE, readData);
+        // 鐩稿綋浜庢妸鎸囬拡閲嶆柊鎸囧悜positon=0
+        originBuf.clear();
+    }
+
+    private void readBodyFromStream(ByteBuffer byteBuffer) throws ReadRecoverableExeption, IOException {
+        // while寰幆鐩村埌byteBuffer瑁呮弧鏁版嵁
+        while (byteBuffer.hasRemaining()) {
+            byte[] bufArray = new byte[socketOptions.getMaxReadBytes()]; // 浠庢湇鍔″櫒鍗曟璇诲彇鐨勬渶澶у��
+            int len = inputStream.read(bufArray);
+            if (len == -1) { // no more data
+                throw new ReadRecoverableExeption("璇绘暟鎹け璐ワ紝鍙兘鏄洜涓簊ocket璺熸湇鍔″櫒鏂紑浜嗚繛鎺�");
+            }
+            int remaining = byteBuffer.remaining();
+            if (len > remaining) { // 浠巗tream璇荤殑鏁版嵁瓒呰繃byteBuffer鐨勫墿浣欑┖闂�
+                byteBuffer.put(bufArray, 0, remaining);
+                // 灏嗗浣欑殑鏁版嵁淇濆瓨鍒皉emainingBuf涓紦瀛橈紝绛変笅涓�娆¤鍙�
+                remainingBuf = ByteBuffer.allocate(len - remaining);
+                remainingBuf.order(socketOptions.getReadOrder());
+                remainingBuf.put(bufArray, remaining, len - remaining);
+            } else { // 浠巗tream璇荤殑鏁版嵁灏忎簬鎴栫瓑浜巄yteBuffer鐨勫墿浣欑┖闂�
+                byteBuffer.put(bufArray, 0, len);
+            }
+        }
+    }
+
+    @Override
+    public void openReader() {
+        init();
+        if (readerThread == null || !readerThread.isAlive()) {
+            readerThread = new Thread(readerTask, "reader thread");
+            stopThread = false;
+            readerThread.start();
+        }
+    }
+
+    @Override
+    public void closeReader() {
+        try {
+            // 鍏抽棴绾跨▼閲婃斁璧勬簮
+            shutDownThread();
+            release();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    // 閲婃斁璧勬簮
+    private void release() {
+        if (originBuf != null) {
+            originBuf = null;
+        }
+        if (remainingBuf != null) {
+            remainingBuf = null;
+        }
+        if (readerThread != null && !readerThread.isAlive()) {
+            readerThread = null;
+        }
+
+        try {
+            if (inputStream != null)
+                inputStream.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            inputStream = null;
+        }
+    }
+
+    // 鍒濆鍖�
+    private void init() {
+        inputStream = connectionManager.getInputStream();
+        // 娌℃湁瀹氫箟娑堟伅鍗忚
+        if (socketOptions.getMessageProtocol() == null) {
+            originBuf = ByteBuffer.allocate(1024 * 4);
+        }
+    }
+
+    @Override
+    public void setOption(EasySocketOptions socketOptions) {
+        this.socketOptions = socketOptions;
+    }
+
+    // 鍏抽棴璇绘暟鎹嚎绋�
+    private void shutDownThread() throws InterruptedException {
+        if (readerThread != null && readerThread.isAlive() && !readerThread.isInterrupted()) {
+            try {
+                stopThread = true;
+                readerThread.interrupt();
+                readerThread.join();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/iowork/EasyWriter.java b/easysocket/src/main/java/com/easysocket/connection/iowork/EasyWriter.java
new file mode 100644
index 0000000..9634e16
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/iowork/EasyWriter.java
@@ -0,0 +1,151 @@
+package com.easysocket.connection.iowork;
+
+import com.easysocket.config.EasySocketOptions;
+import com.easysocket.interfaces.conn.IConnectionManager;
+import com.easysocket.interfaces.conn.ISocketActionDispatch;
+import com.easysocket.interfaces.io.IWriter;
+import com.easysocket.utils.HexUtil;
+import com.easysocket.utils.LogUtil;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.concurrent.LinkedBlockingDeque;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛�
+ */
+public class EasyWriter implements IWriter<EasySocketOptions> {
+
+    /**
+     * 杈撳嚭娴�
+     */
+    private OutputStream outputStream;
+
+    /**
+     * 杩炴帴绠$悊鍣�
+     */
+    private IConnectionManager connectionManager;
+    /**
+     * socket鍙傛暟
+     */
+    private EasySocketOptions socketOptions;
+    /**
+     * 琛屼负鍒嗗彂
+     */
+    private ISocketActionDispatch actionDispatch;
+    /**
+     * 鍐欐暟鎹嚎绋�
+     */
+    private Thread writerThread;
+    /**
+     * 鏄惁鍋滄鍐欐暟鎹�
+     */
+    private boolean isStop;
+    /**
+     * 寰呭啓鍏ユ暟鎹�
+     */
+    private LinkedBlockingDeque<byte[]> packetsToSend = new LinkedBlockingDeque<>();
+
+    public EasyWriter(IConnectionManager connectionManager, ISocketActionDispatch actionDispatch) {
+        this.connectionManager = connectionManager;
+        socketOptions = connectionManager.getOptions();
+        this.actionDispatch = actionDispatch;
+    }
+
+    @Override
+    public void openWriter() {
+        outputStream = connectionManager.getOutStream();
+        if (writerThread == null) {
+            isStop = false;
+            writerThread = new Thread(writerTask, "writer thread");
+            writerThread.start();
+        }
+    }
+
+    @Override
+    public void setOption(EasySocketOptions socketOptions) {
+        this.socketOptions = socketOptions;
+    }
+
+    /**
+     * 鍐欎换鍔�
+     */
+    private Runnable writerTask = new Runnable() {
+        @Override
+        public void run() {
+            // 寰幆鍐欐暟鎹�
+            while (!isStop) {
+                try {
+                    byte[] sender = packetsToSend.take();
+                    write(sender);
+                } catch (InterruptedException | IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    };
+
+    @Override
+    public void write(byte[] sendBytes) throws IOException {
+        if (sendBytes != null) {
+            LogUtil.d("EasyWriter--Socket鍙戦�佹暟鎹甋tring-->" + HexUtil.bytesToHex(sendBytes));
+            LogUtil.d("EasyWriter--Socket鍙戦�佹暟鎹産yte[]-->" + Arrays.toString(sendBytes));
+            int packageSize = socketOptions.getMaxWriteBytes(); // 姣忔鍙互鍙戦�佺殑鏈�澶ф暟鎹�
+            int remainingCount = sendBytes.length;
+            ByteBuffer writeBuf = ByteBuffer.allocate(packageSize);
+            writeBuf.order(socketOptions.getReadOrder());
+            int index = 0;
+            // 濡傛灉鍙戦�佺殑鏁版嵁澶т簬鍗曟鍙彂閫佺殑鏈�澶ф暟鎹紝鍒欏垎澶氭鍙戦��
+            while (remainingCount > 0) {
+                int realWriteLength = Math.min(packageSize, remainingCount);
+                writeBuf.clear(); // 娓呯┖缂撳瓨
+                writeBuf.rewind(); // 灏唒osition浣嶇疆绉诲埌0
+                writeBuf.put(sendBytes, index, realWriteLength);
+                writeBuf.flip();
+                byte[] writeArr = new byte[realWriteLength];
+                writeBuf.get(writeArr);
+                outputStream.write(writeArr);
+                outputStream.flush(); // 寮哄埗鍐欏叆缂撳瓨涓畫鐣欐暟鎹�
+                index += realWriteLength;
+                remainingCount -= realWriteLength;
+            }
+        }
+    }
+
+    @Override
+    public void offer(byte[] sender) {
+        if (!isStop)
+            packetsToSend.offer(sender);
+    }
+
+    @Override
+    public void closeWriter() {
+        try {
+            if (outputStream != null)
+                outputStream.close();
+            shutDownThread();
+        } catch (IOException | InterruptedException e) {
+            e.printStackTrace();
+        } finally {
+            outputStream = null;
+        }
+    }
+
+    private void shutDownThread() throws InterruptedException {
+        if (writerThread != null && writerThread.isAlive() && !writerThread.isInterrupted()) {
+            try {
+                isStop = true;
+                writerThread.interrupt();
+                writerThread.join();
+                writerThread = null;
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/iowork/IOManager.java b/easysocket/src/main/java/com/easysocket/connection/iowork/IOManager.java
new file mode 100644
index 0000000..b1bd280
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/iowork/IOManager.java
@@ -0,0 +1,98 @@
+package com.easysocket.connection.iowork;
+
+import com.easysocket.config.EasySocketOptions;
+import com.easysocket.interfaces.config.IOptions;
+import com.easysocket.interfaces.conn.IConnectionManager;
+import com.easysocket.interfaces.conn.ISocketActionDispatch;
+import com.easysocket.interfaces.io.IIOManager;
+import com.easysocket.interfaces.io.IReader;
+import com.easysocket.interfaces.io.IWriter;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/5/28
+ * Note锛�
+ */
+public class IOManager implements IIOManager, IOptions {
+    /**
+     * socket琛屼负鍥炶皟
+     */
+    private ISocketActionDispatch actionDispatch;
+    /**
+     * 杩炴帴绠$悊
+     */
+    private IConnectionManager connectionManager;
+    /**
+     * 鍐�
+     */
+    private IWriter writer;
+    /**
+     * 璇�
+     */
+    private IReader reader;
+
+    public IOManager(IConnectionManager connectionManager,
+                     ISocketActionDispatch connActionDispatch) {
+        this.connectionManager = connectionManager;
+        this.actionDispatch = connActionDispatch;
+        initIO();
+    }
+
+    //  鍒濆鍖杋o
+    private void initIO() {
+        //makesureHeaderProtocolNotEmpty();
+        reader = new EasyReader(connectionManager, actionDispatch); //  璇�
+        writer = new EasyWriter(connectionManager, actionDispatch); //  鍐�
+    }
+
+    @Override
+    public void sendBytes(byte[] bytes) {
+        if (writer != null)
+            writer.offer(bytes);
+    }
+
+    @Override
+    public void startIO() {
+        if (writer != null)
+            writer.openWriter();
+        if (reader != null)
+            reader.openReader();
+    }
+
+    @Override
+    public void closeIO() {
+        if (writer != null)
+            writer.closeWriter();
+        if (reader != null)
+            reader.closeReader();
+    }
+
+    @Override
+    public Object setOptions(EasySocketOptions socketOptions) {
+        //makesureHeaderProtocolNotEmpty();
+        if (writer != null)
+            writer.setOption(socketOptions);
+        if (reader != null)
+            reader.setOption(socketOptions);
+        return this;
+    }
+
+    @Override
+    public EasySocketOptions getOptions() {
+        return connectionManager.getOptions();
+    }
+
+    /**
+     * 纭繚鍖呯粨鏋勫崗璁笉涓虹┖
+     */
+//    private void makesureHeaderProtocolNotEmpty() {
+//        IMessageProtocol protocol = connectionManager.getOptions().getMessageProtocol();
+//        if (protocol == null) {
+//            throw new NoNullException("The reader protocol can not be Null.");
+//        }
+//
+//        if (protocol.getHeaderLength() == 0) {
+//            throw new NoNullException("The header length can not be zero.");
+//        }
+//    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/reconnect/AbsReconnection.java b/easysocket/src/main/java/com/easysocket/connection/reconnect/AbsReconnection.java
new file mode 100644
index 0000000..81e77ff
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/reconnect/AbsReconnection.java
@@ -0,0 +1,52 @@
+package com.easysocket.connection.reconnect;
+
+import com.easysocket.entity.OriginReadData;
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.interfaces.conn.IConnectionManager;
+import com.easysocket.interfaces.conn.IReconnListener;
+import com.easysocket.interfaces.conn.SocketActionListener;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/5/31
+ * Note锛氭娊璞¢噸杩炲櫒
+ */
+public abstract class AbsReconnection extends SocketActionListener implements IReconnListener {
+    /**
+     * 杩炴帴绠$悊鍣�
+     */
+    protected IConnectionManager connectionManager;
+    /**
+     * socket杩炴帴绠$悊鍣ㄦ槸鍚﹀凡閿�姣�
+     */
+    protected boolean isDetach;
+
+
+    @Override
+    public synchronized void attach(IConnectionManager iConnectionManager) {
+        if (!isDetach) {
+            detach();
+        }
+        isDetach = false;
+        connectionManager = iConnectionManager;
+        connectionManager.subscribeSocketAction(this); // 鐩戝惉socket琛屼负
+    }
+
+    @Override
+    public synchronized void detach() {
+        isDetach = true;
+        if (connectionManager != null)
+            connectionManager.unSubscribeSocketAction(this);
+    }
+
+    @Override
+    public void onSocketResponse(SocketAddress socketAddress, OriginReadData originReadData) {
+        // donothing
+    }
+
+    /**
+     * 鏄惁姝e湪閲嶈繛
+     * @return
+     */
+    public abstract boolean isReconning();
+}
diff --git a/easysocket/src/main/java/com/easysocket/connection/reconnect/DefaultReConnection.java b/easysocket/src/main/java/com/easysocket/connection/reconnect/DefaultReConnection.java
new file mode 100644
index 0000000..959563d
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/connection/reconnect/DefaultReConnection.java
@@ -0,0 +1,148 @@
+package com.easysocket.connection.reconnect;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.interfaces.conn.IConnectionManager;
+import com.easysocket.utils.LogUtil;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/5/28
+ * Note锛氶粯璁ら噸杩炲櫒
+ */
+public class DefaultReConnection extends AbsReconnection {
+    /**
+     * 鏈�澶ц繛鎺ュけ璐ユ鏁帮紝瓒呰繃鍙互鍒囨崲鍒板鐢ㄧ殑鏈嶅姟鍣ㄥ湴鍧�
+     */
+    private static final int MAX_CONNECTION_FAILED_TIMES = 10;
+    /**
+     * 杩炴帴澶辫触鐨勬鏁�
+     */
+    private int connectionFailedTimes = 0;
+    /**
+     * 閲嶈繛闂撮殧涓嶈兘灏忎簬10绉掞紝涓轰簡閬垮厤鍏ㄩ儴瀹㈡埛绔痵ocket鍦ㄥ悓涓�鏃堕棿杩炴帴鏈嶅姟绔紝闂撮殧鏃堕棿闇�瑕佷笂涓嬫诞鍔�50%
+     */
+    private long reconnectTimeDelay = 10 * 1000;
+    /**
+     * 閲嶈繛绾跨▼
+     */
+    private HandlerThread handlerThread;
+    /**
+     * 瀹炵幇寤舵椂浠诲姟鐨� handler
+     */
+    private Handler handler;
+
+    public DefaultReConnection() {
+    }
+
+    @Override
+    public synchronized void attach(IConnectionManager iConnectionManager) {
+        super.attach(iConnectionManager);
+        if (reconnectTimeDelay < connectionManager.getOptions().getConnectTimeout()) {
+            reconnectTimeDelay = connectionManager.getOptions().getConnectTimeout();
+        }
+    }
+
+    /**
+     * 閲嶈繛浠诲姟
+     */
+    private final Runnable RcConnTask = new Runnable() {
+        @Override
+        public void run() {
+            LogUtil.d("---> 鎵ц閲嶈繛");
+            if (isDetach) {
+                shutDown();
+                return;
+            }
+            // 鏄惁鍙繛鎺ョ殑
+            if (!connectionManager.isConnectViable()) {
+                LogUtil.d("褰撳墠鏉′欢涓嶅厑璁歌繛鎺�");
+                // 灏濊瘯鍐嶆閲嶈繛
+                handler.postDelayed(RcConnTask, (long) (reconnectTimeDelay * (Math.random() + 0.5)));
+                return;
+            }
+            // 閲嶈繛
+            connectionManager.connect();
+        }
+    };
+
+    /**
+     * 杩涜閲嶈繛
+     */
+    private void reconnect() {
+        if (handlerThread == null) {
+            handlerThread = new HandlerThread("re_conn");
+            handlerThread.start();
+            handler = new Handler(handlerThread.getLooper());
+        }
+        LogUtil.d("閲嶈繛闂撮殧鏃堕棿-->" + reconnectTimeDelay * (Math.random() + 0.5));
+        handler.postDelayed(RcConnTask, (long) (reconnectTimeDelay * (Math.random() + 0.5)));
+    }
+
+
+    // 鍏抽棴閲嶈繛绾跨▼
+    private void shutDown() {
+        if (handlerThread != null && handlerThread.isAlive()) {
+            handlerThread.quit();
+            handlerThread = null;
+            handler = null;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        // getClass杩斿洖Class绫诲瀷鐨勫璞★紝姣旇緝瀹冧滑鐨勭被鍨嬪璞℃槸鍚�==锛屽叾瀹炴槸姣旇緝瀹冧滑鏄惁涓哄悓涓�涓狢lass鍒涘缓鐨勫璞�
+        if (o == null || getClass() != o.getClass()) return false;
+        return true;
+    }
+
+    @Override
+    public void onSocketConnSuccess(SocketAddress socketAddress) {
+        // 杩炴帴鎴愬姛鍏抽棴閲嶈繛绾跨▼
+        shutDown();
+    }
+
+    @Override
+    public void onSocketConnFail(SocketAddress socketAddress, boolean isNeedReconnect) {
+        // 涓嶉渶瑕侀噸杩烇紝鍒欏叧闂噸杩炵嚎绋�
+        if (!isNeedReconnect) {
+            shutDown();
+            return;
+        }
+        connectionFailedTimes++;
+
+        // 濡傛灉澶т簬鏈�澶ц繛鎺ユ鏁板苟涓旀湁澶囩敤host,鍒欒疆娴佸垏鎹袱涓猦ost
+        if (connectionFailedTimes > MAX_CONNECTION_FAILED_TIMES && socketAddress.getBackupAddress() != null) {
+            connectionFailedTimes = 0; // 褰掗浂
+            SocketAddress backupAddress = socketAddress.getBackupAddress();
+            SocketAddress nowAddress = new SocketAddress(socketAddress.getIp(), socketAddress.getPort());
+            backupAddress.setBackupAddress(nowAddress);
+            if (connectionManager.isConnectViable()) {
+                connectionManager.switchHost(backupAddress);
+                // 鍒囨崲涓绘満鍦板潃锛岄噸鏂拌繛鎺�
+                reconnect();
+            }
+        } else {
+            reconnect();
+        }
+
+    }
+
+    @Override
+    public void onSocketDisconnect(SocketAddress socketAddress, boolean isNeedReconnect) {
+        // 鏄惁闇�瑕侀噸杩�
+        if (!isNeedReconnect) {
+            shutDown();
+            return;
+        }
+        reconnect();
+    }
+
+    @Override
+    public boolean isReconning() {
+        return handlerThread != null && handlerThread.isAlive();
+    }
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/entity/OriginReadData.java b/easysocket/src/main/java/com/easysocket/entity/OriginReadData.java
new file mode 100644
index 0000000..da184c6
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/entity/OriginReadData.java
@@ -0,0 +1,58 @@
+package com.easysocket.entity;
+
+import com.easysocket.EasySocket;
+import com.easysocket.utils.Utils;
+
+import java.io.Serializable;
+import java.nio.charset.Charset;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛氳鍒扮殑鏁版嵁
+ */
+public class OriginReadData implements Serializable {
+
+    /**
+     * 鍖呭ご鏁版嵁
+     */
+    private byte[] headerData;
+    /**
+     * 鍖呬綋鏁版嵁
+     */
+    private byte[] bodyData;
+
+    public byte[] getHeaderData() {
+        return headerData;
+    }
+
+    public void setHeaderData(byte[] headerData) {
+        this.headerData = headerData;
+    }
+
+    public byte[] getBodyBytes() {
+        return bodyData;
+    }
+
+    public void setBodyData(byte[] bodyData) {
+        this.bodyData = bodyData;
+    }
+
+    /**
+     * 鑾峰彇鏁版嵁body鐨剆tring
+     *
+     * @return
+     */
+    public String getBodyString() {
+        return new String(getBodyBytes(), Charset.forName(EasySocket.getInstance().getDefOptions().getCharsetName()));
+    }
+
+    /**
+     * 鑾峰彇瀹屾暣鐨勬暟鎹紝鍖呮嫭鍖呭ご鍜屽寘浣�
+     *
+     * @return
+     */
+    public byte[] getOriginDataBytes() {
+        return Utils.concatBytes(getHeaderData(), getBodyBytes());
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/entity/SocketAddress.java b/easysocket/src/main/java/com/easysocket/entity/SocketAddress.java
new file mode 100644
index 0000000..a4187eb
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/entity/SocketAddress.java
@@ -0,0 +1,54 @@
+package com.easysocket.entity;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/5/31
+ * Note锛歴ocket涓绘満鍦板潃
+ */
+public class SocketAddress {
+
+    /**
+     * IPV4鍦板潃
+     */
+    private String ip;
+    /**
+     * 杩炴帴鏈嶅姟鍣ㄧ鍙e彿
+     */
+    private int port;
+    /**
+     * 褰撴IP鍦板潃Ping涓嶉�氭椂鐨勫鐢↖P
+     */
+    private SocketAddress backupAddress;
+
+    /**
+     * 鑾峰彇澶囩敤鐨処p鍜岀鍙e彿
+     *
+     * @return 澶囩敤鐨勭鍙e彿鍜孖P鍦板潃
+     */
+    public SocketAddress getBackupAddress() {
+        return backupAddress;
+    }
+
+    /**
+     * 璁剧疆澶囩敤鐨処P鍜岀鍙e彿,鍙互涓嶈缃�
+     *
+     * @param backupAddress 澶囩敤鐨処P鍜岀鍙e彿淇℃伅
+     */
+    public void setBackupAddress(SocketAddress backupAddress) {
+        this.backupAddress = backupAddress;
+    }
+
+    public SocketAddress(String ip, int port){
+        this.ip =ip;
+        this.port =port;
+    }
+
+    public String getIp() {
+        return ip;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/entity/basemsg/IResponse.java b/easysocket/src/main/java/com/easysocket/entity/basemsg/IResponse.java
new file mode 100644
index 0000000..9e08c7c
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/entity/basemsg/IResponse.java
@@ -0,0 +1,9 @@
+package com.easysocket.entity.basemsg;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/12/8
+ * Note锛�
+ */
+public interface IResponse {
+}
diff --git a/easysocket/src/main/java/com/easysocket/entity/basemsg/ISender.java b/easysocket/src/main/java/com/easysocket/entity/basemsg/ISender.java
new file mode 100644
index 0000000..4f34083
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/entity/basemsg/ISender.java
@@ -0,0 +1,11 @@
+package com.easysocket.entity.basemsg;
+
+import java.io.Serializable;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛氬彂閫佹暟鎹殑鎺ュ彛
+ */
+public interface ISender extends Serializable {
+}
diff --git a/easysocket/src/main/java/com/easysocket/entity/basemsg/SuperCallbackResponse.java b/easysocket/src/main/java/com/easysocket/entity/basemsg/SuperCallbackResponse.java
new file mode 100644
index 0000000..7bdb330
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/entity/basemsg/SuperCallbackResponse.java
@@ -0,0 +1,13 @@
+package com.easysocket.entity.basemsg;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/12/7
+ */
+public abstract class SuperCallbackResponse implements IResponse {
+
+    public abstract String getCallbackId();
+
+    public abstract void setCallbackId(String callbackId);
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/entity/basemsg/SuperCallbackSender.java b/easysocket/src/main/java/com/easysocket/entity/basemsg/SuperCallbackSender.java
new file mode 100644
index 0000000..2f1480d
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/entity/basemsg/SuperCallbackSender.java
@@ -0,0 +1,36 @@
+package com.easysocket.entity.basemsg;
+
+import com.easysocket.utils.Utils;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/10/19
+ */
+public abstract class SuperCallbackSender extends SuperSender {
+
+    private String callbackId;
+
+    public SuperCallbackSender() {
+        generateCallbackId();
+    }
+
+    public String getCallbackId() {
+        return callbackId;
+    }
+
+    /**
+     * 鏍规嵁鑷繁鐨勫崗璁墦鍖呮秷鎭�
+     *
+     * @return
+     */
+    public abstract byte[] pack();
+
+    /**
+     * 闅忔満鐢熸垚涓�涓洖璋冩爣璇� CallbackId锛屽湪娑堟伅鍙戦�佸墠鎵ц锛孋allbackId浣滀负娑堟伅鐨勫敮涓�鏍囪瘑涓�璧蜂紶缁欐湇鍔″櫒锛屾湇鍔″櫒鍙嶉
+     * 褰撳墠娑堟伅鐨勬椂鍊欎篃鏄惡甯﹀悓鏍风殑CallbackId缁欏鎴风锛岀敤浠ヨ瘑鍒�
+     */
+    public void generateCallbackId() {
+        callbackId= Utils.getRandomChar(20);
+    }
+}
+
diff --git a/easysocket/src/main/java/com/easysocket/entity/basemsg/SuperSender.java b/easysocket/src/main/java/com/easysocket/entity/basemsg/SuperSender.java
new file mode 100644
index 0000000..e700263
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/entity/basemsg/SuperSender.java
@@ -0,0 +1,9 @@
+package com.easysocket.entity.basemsg;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/10/19
+ * Note锛氬熀纭�娑堟伅
+ */
+public class SuperSender implements ISender {
+}
diff --git a/easysocket/src/main/java/com/easysocket/exception/InitialExeption.java b/easysocket/src/main/java/com/easysocket/exception/InitialExeption.java
new file mode 100644
index 0000000..772306d
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/exception/InitialExeption.java
@@ -0,0 +1,12 @@
+package com.easysocket.exception;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/5
+ * Note锛氬垵濮嬪寲寮傚父
+ */
+public class InitialExeption extends RuntimeException{
+    public InitialExeption(String s){
+        super(s);
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/exception/NotNullException.java b/easysocket/src/main/java/com/easysocket/exception/NotNullException.java
new file mode 100644
index 0000000..dc5092e
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/exception/NotNullException.java
@@ -0,0 +1,12 @@
+package com.easysocket.exception;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/5
+ * Note锛氶潪绌哄紓甯�
+ */
+public class NotNullException extends RuntimeException {
+    public NotNullException(String e) {
+        super(e);
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/exception/ReadRecoverableExeption.java b/easysocket/src/main/java/com/easysocket/exception/ReadRecoverableExeption.java
new file mode 100644
index 0000000..ad70ee2
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/exception/ReadRecoverableExeption.java
@@ -0,0 +1,13 @@
+package com.easysocket.exception;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/5
+ * Note锛氬彲鎭㈠socket璇绘暟鎹紓甯�
+ */
+public class ReadRecoverableExeption extends Exception {
+
+    public ReadRecoverableExeption(String s){
+        super(s);
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/exception/ReadUnrecoverableException.java b/easysocket/src/main/java/com/easysocket/exception/ReadUnrecoverableException.java
new file mode 100644
index 0000000..26c1956
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/exception/ReadUnrecoverableException.java
@@ -0,0 +1,12 @@
+package com.easysocket.exception;
+
+/**
+ * Author锛歁apogo
+ * Date锛�2020/12/29
+ * Note锛氫笉鍙慨澶嶇殑璇诲彇閿欒
+ */
+public class ReadUnrecoverableException extends Exception {
+    public ReadUnrecoverableException(String s) {
+        super(s);
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/exception/RequestCancelException.java b/easysocket/src/main/java/com/easysocket/exception/RequestCancelException.java
new file mode 100644
index 0000000..f899342
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/exception/RequestCancelException.java
@@ -0,0 +1,13 @@
+package com.easysocket.exception;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/4
+ * Note锛氳姹傚彇娑堝紓甯�
+ */
+public class RequestCancelException extends Exception{
+
+    public RequestCancelException(String s){
+        super(s);
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/exception/RequestTimeOutException.java b/easysocket/src/main/java/com/easysocket/exception/RequestTimeOutException.java
new file mode 100644
index 0000000..51768ae
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/exception/RequestTimeOutException.java
@@ -0,0 +1,13 @@
+package com.easysocket.exception;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/4
+ * Note锛氳姹傝秴鏃跺紓甯�
+ */
+public class RequestTimeOutException extends Exception{
+
+    public RequestTimeOutException(String s){
+        super(s);
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/callback/ICallBack.java b/easysocket/src/main/java/com/easysocket/interfaces/callback/ICallBack.java
new file mode 100644
index 0000000..5c48e23
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/callback/ICallBack.java
@@ -0,0 +1,18 @@
+package com.easysocket.interfaces.callback;
+
+import com.easysocket.callback.SuperCallBack;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/5
+ * Note锛�
+ */
+public interface ICallBack {
+    /**
+     * socket璇锋眰鍥炶皟
+     * @param callBack
+     */
+    void onCallBack(SuperCallBack callBack);
+
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/callback/IProgressDialog.java b/easysocket/src/main/java/com/easysocket/interfaces/callback/IProgressDialog.java
new file mode 100644
index 0000000..3e66dae
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/callback/IProgressDialog.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2017 zhouyou(478319399@qq.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.easysocket.interfaces.callback;
+
+import android.app.Dialog;
+
+/**
+ * <p>鎻忚堪锛氳嚜瀹氫箟瀵硅瘽妗嗙殑dialog</p>
+ */
+public interface IProgressDialog {
+    Dialog getDialog();
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/callback/IType.java b/easysocket/src/main/java/com/easysocket/interfaces/callback/IType.java
new file mode 100644
index 0000000..4193247
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/callback/IType.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2017 zhouyou(478319399@qq.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.easysocket.interfaces.callback;
+
+import java.lang.reflect.Type;
+
+/**
+ * <p>鎻忚堪锛氳幏鍙栫被鍨嬫帴鍙�</p>
+ */
+public interface IType<T> {
+
+    Type getType();
+
+    Class<?> getGenericityClazz();
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/callback/ProgressCancelListener.java b/easysocket/src/main/java/com/easysocket/interfaces/callback/ProgressCancelListener.java
new file mode 100644
index 0000000..c64e9f5
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/callback/ProgressCancelListener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 zhouyou(478319399@qq.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.easysocket.interfaces.callback;
+
+/**
+ * <p>鎻忚堪锛氳繘搴︽鍙栨秷鐩戝惉</p>
+ */
+public interface ProgressCancelListener {
+    void onCancelProgress();
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/config/IConnectionSwitchListener.java b/easysocket/src/main/java/com/easysocket/interfaces/config/IConnectionSwitchListener.java
new file mode 100644
index 0000000..1260c5d
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/config/IConnectionSwitchListener.java
@@ -0,0 +1,13 @@
+package com.easysocket.interfaces.config;
+
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.interfaces.conn.IConnectionManager;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/4
+ * Note锛�
+ */
+public interface IConnectionSwitchListener {
+    void onSwitchConnectionInfo(IConnectionManager manager, SocketAddress oldAddress, SocketAddress newAddress);
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/config/IMessageProtocol.java b/easysocket/src/main/java/com/easysocket/interfaces/config/IMessageProtocol.java
new file mode 100644
index 0000000..0808511
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/config/IMessageProtocol.java
@@ -0,0 +1,20 @@
+package com.easysocket.interfaces.config;
+
+import java.nio.ByteOrder;
+
+/**
+ * 娑堟伅鏁版嵁鏍煎紡
+ */
+public interface IMessageProtocol {
+
+    /**
+     * 鑾峰彇鍖呭ご鐨勯暱搴�
+     */
+    int getHeaderLength();
+
+    /**
+     * 鑾峰彇鏁版嵁鍖呬綋鐨勯暱搴︼紝鏍规嵁鍗忚杩欎釜闀垮害搴旇鍐欏湪鍖呭ご涓紝鍦ㄨ鍙栨暟鎹椂鐢ㄥ埌
+     */
+    int getBodyLength(byte[] header, ByteOrder byteOrder);
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/config/IOptions.java b/easysocket/src/main/java/com/easysocket/interfaces/config/IOptions.java
new file mode 100644
index 0000000..f732839
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/config/IOptions.java
@@ -0,0 +1,22 @@
+package com.easysocket.interfaces.config;
+
+import com.easysocket.config.EasySocketOptions;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛�
+ */
+public interface IOptions<T> {
+    /**
+     * 璁剧疆閰嶇疆淇℃伅
+     * @param socketOptions
+     */
+    T setOptions(EasySocketOptions socketOptions);
+
+    /**
+     * 鑾峰彇閰嶇疆淇℃伅
+     * @return
+     */
+    EasySocketOptions getOptions();
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/conn/IConnectionManager.java b/easysocket/src/main/java/com/easysocket/interfaces/conn/IConnectionManager.java
new file mode 100644
index 0000000..94d88ed
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/conn/IConnectionManager.java
@@ -0,0 +1,65 @@
+package com.easysocket.interfaces.conn;
+
+import com.easysocket.entity.SocketAddress;
+import com.easysocket.interfaces.callback.ICallBack;
+import com.easysocket.interfaces.config.IOptions;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/5/29
+ * Note锛氳繛鎺ョ鐞嗙殑鎺ュ彛瑙勮寖
+ */
+public interface IConnectionManager extends ISubscribeSocketAction, IOptions<IConnectionManager>,ISend, ICallBack {
+    /**
+     * 寮�濮嬭繛鎺�
+     */
+    void connect();
+
+    /**
+     * 鍏抽棴杩炴帴
+     * @param isNeedReconnect 鏄惁闇�瑕侀噸杩�
+     */
+    void disconnect(boolean isNeedReconnect);
+
+
+    /**
+     * 鑾峰彇socket杩炴帴鐘舵��
+     * @return
+     */
+    int getConnectionStatus();
+
+    /**
+     * 鏄惁鍙繛鎺ョ殑
+     * @return
+     */
+    boolean isConnectViable();
+
+    /**
+     * 鍒囨崲host
+     * @param socketAddress
+     */
+    void switchHost(SocketAddress socketAddress);
+
+    /**
+     * 鑾峰彇杈撳叆娴�
+     * @return
+     */
+    InputStream getInputStream();
+
+    /**
+     * 鑾峰彇杈撳嚭娴�
+     * @return
+     */
+    OutputStream getOutStream();
+
+    /**
+     * 鑾峰彇蹇冭烦绠$悊鍣�
+     * @return
+     */
+    IHeartManager getHeartManager();
+
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/conn/IHeartManager.java b/easysocket/src/main/java/com/easysocket/interfaces/conn/IHeartManager.java
new file mode 100644
index 0000000..5bbad47
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/conn/IHeartManager.java
@@ -0,0 +1,28 @@
+package com.easysocket.interfaces.conn;
+
+import com.easysocket.connection.heartbeat.HeartManager;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/12/8
+ * Note锛�
+ */
+public interface IHeartManager {
+
+    /**
+     * 寮�濮嬪績璺�
+     * @param clientHeart
+     */
+    void startHeartbeat(byte[] clientHeart, HeartManager.HeartbeatListener listener);
+
+    /**
+     * 鍋滄蹇冭烦
+     */
+    void stopHeartbeat();
+
+
+    /**
+     * 鎺ユ敹鍒板績璺�
+     */
+    void onReceiveHeartBeat();
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/conn/IReconnListener.java b/easysocket/src/main/java/com/easysocket/interfaces/conn/IReconnListener.java
new file mode 100644
index 0000000..ed48ac1
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/conn/IReconnListener.java
@@ -0,0 +1,20 @@
+package com.easysocket.interfaces.conn;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛�
+ */
+public interface IReconnListener {
+
+    /**
+     * 鍏宠仈杩炴帴鍣�
+     * @param iConnectionManager
+     */
+    void attach(IConnectionManager iConnectionManager);
+
+    /**
+     * 鍒嗙杩炴帴鍣�
+     */
+    void detach();
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/conn/ISend.java b/easysocket/src/main/java/com/easysocket/interfaces/conn/ISend.java
new file mode 100644
index 0000000..c9cd772
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/conn/ISend.java
@@ -0,0 +1,25 @@
+package com.easysocket.interfaces.conn;
+
+import com.easysocket.entity.basemsg.SuperCallbackSender;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/5
+ * Note锛氬彂閫佹帴鍙�
+ */
+public interface ISend {
+
+    /**
+     * 鍙戦�佷竴涓湁鍥炶皟鐨勬秷鎭�
+     * @param sender
+     * @return
+     */
+    IConnectionManager upCallbackMessage(SuperCallbackSender sender);
+
+    /**
+     * 鍙戦�乥ytes
+     * @param bytes
+     * @return
+     */
+    IConnectionManager upBytes(byte[] bytes);
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/conn/ISocketActionDispatch.java b/easysocket/src/main/java/com/easysocket/interfaces/conn/ISocketActionDispatch.java
new file mode 100644
index 0000000..c028978
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/conn/ISocketActionDispatch.java
@@ -0,0 +1,38 @@
+package com.easysocket.interfaces.conn;
+
+import java.io.Serializable;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛歴ocket琛屼负鍒嗗彂鎺ュ彛
+ */
+public interface ISocketActionDispatch {
+    /**
+     * 鍋滄鍒嗗彂绾跨▼
+     */
+    void stopDispatchThread();
+
+    void startDispatchThread();
+
+    void dispatchAction(String action);
+
+    /**
+     * socket琛屼负鐨勫垎鍙�
+     * @param action
+     * @param serializable
+     */
+    void dispatchAction(String action, Serializable serializable);
+
+    /**
+     * 璁㈤槄socket琛屼负
+     * @param iSocketActionListener
+     */
+    void subscribe(ISocketActionListener iSocketActionListener);
+
+    /**
+     * 瑙i櫎socket琛屼负鐨勮闃�
+     * @param iSocketActionListener
+     */
+    void unsubscribe(ISocketActionListener iSocketActionListener);
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/conn/ISocketActionListener.java b/easysocket/src/main/java/com/easysocket/interfaces/conn/ISocketActionListener.java
new file mode 100644
index 0000000..82ecb60
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/conn/ISocketActionListener.java
@@ -0,0 +1,52 @@
+package com.easysocket.interfaces.conn;
+
+import com.easysocket.entity.OriginReadData;
+import com.easysocket.entity.SocketAddress;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛歴ocket琛屼负鐩戝惉鎺ュ彛
+ */
+public interface ISocketActionListener {
+    /**
+     * socket杩炴帴鎴愬姛
+     * @param socketAddress
+     */
+    void onSocketConnSuccess(SocketAddress socketAddress);
+
+    /**
+     * socket杩炴帴澶辫触
+     * @param socketAddress
+     * @param isNeedReconnect 鏄惁闇�瑕侀噸杩�
+     */
+    void onSocketConnFail(SocketAddress socketAddress, boolean isNeedReconnect);
+
+    /**
+     * 鏂紑socket杩炴帴
+     * @param socketAddress
+     * @param isNeedReconnect 鏄惁闇�瑕侀噸杩�
+     */
+    void onSocketDisconnect(SocketAddress socketAddress, boolean isNeedReconnect);
+
+    /**
+     * socket鏁版嵁鍝嶅簲
+     * @param socketAddress
+     * @param originReadData
+     */
+    void onSocketResponse(SocketAddress socketAddress, OriginReadData originReadData);
+
+    /**
+     * socket鏁版嵁鍝嶅簲
+     * @param socketAddress
+     * @param readData
+     */
+    void onSocketResponse(SocketAddress socketAddress, String readData);
+
+    /**
+     * socket鏁版嵁鍝嶅簲
+     * @param socketAddress
+     * @param readData
+     */
+    void onSocketResponse(SocketAddress socketAddress, byte[] readData);
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/conn/ISubscribeSocketAction.java b/easysocket/src/main/java/com/easysocket/interfaces/conn/ISubscribeSocketAction.java
new file mode 100644
index 0000000..27fc89e
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/conn/ISubscribeSocketAction.java
@@ -0,0 +1,20 @@
+package com.easysocket.interfaces.conn;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛氳闃呯洃鍚瑂ocket
+ */
+public interface ISubscribeSocketAction {
+    /**
+     * 娉ㄥ唽鐩戝惉socket鐨勮涓�
+     * @param iSocketActionListener
+     */
+    void subscribeSocketAction(ISocketActionListener iSocketActionListener);
+
+    /**
+     * 娉ㄩ攢鐩戝惉socket鐨勮涓�
+     * @param iSocketActionListener
+     */
+    void unSubscribeSocketAction(ISocketActionListener iSocketActionListener);
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/conn/SocketActionListener.java b/easysocket/src/main/java/com/easysocket/interfaces/conn/SocketActionListener.java
new file mode 100644
index 0000000..a63a874
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/conn/SocketActionListener.java
@@ -0,0 +1,57 @@
+package com.easysocket.interfaces.conn;
+
+import com.easysocket.entity.OriginReadData;
+import com.easysocket.entity.SocketAddress;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/4
+ * Note锛歴ocket琛屼负鐩戝惉鐨勬娊璞$被锛岀户鎵挎绫诲彲浠ラ�夋嫨鎬у湴閲嶅啓鏂规硶
+ */
+public abstract class SocketActionListener implements ISocketActionListener{
+    /**
+     * socket杩炴帴鎴愬姛
+     * @param socketAddress
+     */
+    @Override
+    public void onSocketConnSuccess(SocketAddress socketAddress) {
+
+    }
+    /**
+     * socket杩炴帴澶辫触
+     * @param socketAddress
+     * @param isNeedReconnect 鏄惁闇�瑕侀噸杩�
+     */
+    @Override
+    public void onSocketConnFail(SocketAddress socketAddress, boolean isNeedReconnect) {
+
+    }
+    /**
+     * 鏂紑socket杩炴帴
+     * @param socketAddress
+     * @param isNeedReconnect 鏄惁闇�瑕侀噸杩�
+     */
+    @Override
+    public void onSocketDisconnect(SocketAddress socketAddress, boolean isNeedReconnect) {
+
+    }
+    /**
+     * socket璇绘暟鎹弽棣�
+     * @param socketAddress
+     * @param originReadData
+     */
+    @Override
+    public void onSocketResponse(SocketAddress socketAddress, OriginReadData originReadData) {
+
+    }
+
+    @Override
+    public void onSocketResponse(SocketAddress socketAddress, byte[] readData) {
+
+    }
+
+    @Override
+    public void onSocketResponse(SocketAddress socketAddress, String readData) {
+
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/io/IIOManager.java b/easysocket/src/main/java/com/easysocket/interfaces/io/IIOManager.java
new file mode 100644
index 0000000..3cdf538
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/io/IIOManager.java
@@ -0,0 +1,27 @@
+package com.easysocket.interfaces.io;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛�
+ */
+public interface IIOManager {
+
+    /**
+     * 鍙戦�佸瓧鑺傛祦
+     *
+     * @param bytes
+     */
+    void sendBytes(byte[] bytes);
+
+    /**
+     * 鍏抽棴io绠$悊鍣�
+     */
+    void closeIO();
+
+    /**
+     * 寮�鍚痠o鎿嶄綔
+     */
+    void startIO();
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/io/IReader.java b/easysocket/src/main/java/com/easysocket/interfaces/io/IReader.java
new file mode 100644
index 0000000..3104c06
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/io/IReader.java
@@ -0,0 +1,32 @@
+package com.easysocket.interfaces.io;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛�
+ */
+public interface IReader<T> {
+
+    /**
+     * 璇绘暟鎹�
+     */
+    void read() throws Exception;
+
+    /**
+     * 鎵撳紑鏁版嵁鐨勮鍙�
+     */
+    void openReader();
+
+    /**
+     * 鍏抽棴鏁版嵁鐨勮鍙�
+     */
+    void closeReader();
+
+    /**
+     * 璁剧疆鍙傛暟
+     * @param t
+     */
+    void setOption(T t);
+
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/interfaces/io/IWriter.java b/easysocket/src/main/java/com/easysocket/interfaces/io/IWriter.java
new file mode 100644
index 0000000..644e7f5
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/interfaces/io/IWriter.java
@@ -0,0 +1,38 @@
+package com.easysocket.interfaces.io;
+
+import java.io.IOException;
+
+/**
+ * Author锛欰lex
+ * Date锛�2019/6/1
+ * Note锛�
+ */
+public interface IWriter<T> {
+    /**
+     * 淇濆瓨瑕佸啓鐨勬暟鎹�
+     */
+    void offer(byte[] sender);
+
+    /**
+     * 鍐欐暟鎹�
+     * @param sender
+     */
+    void write(byte[] sender) throws IOException;
+
+    /**
+     * 鍏抽棴stream
+     */
+    void closeWriter();
+
+    /**
+     * 寮�鍚啓鏁版嵁
+     */
+    void openWriter();
+
+    /**
+     * 璁剧疆鍙傛暟
+     * @param t
+     */
+    void setOption(T t);
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/utils/HexUtil.java b/easysocket/src/main/java/com/easysocket/utils/HexUtil.java
new file mode 100644
index 0000000..a92049b
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/utils/HexUtil.java
@@ -0,0 +1,275 @@
+package com.easysocket.utils;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Copyright (C), 2022,
+ * Author: zuo
+ * Date: 2022/3/9 14:55
+ * Description:
+ */
+public class HexUtil {
+
+
+    /**
+     * hex瀛楃涓茶浆byte鏁扮粍
+     *
+     * @param inHex 寰呰浆鎹㈢殑Hex瀛楃涓�
+     * @return 杞崲鍚庣殑byte鏁扮粍缁撴灉
+     */
+    public static byte[] hexToByteArray(String inHex) {
+        int hexlen = inHex.length();
+        byte[] result;
+        if (hexlen % 2 == 1) {
+            //濂囨暟
+            hexlen++;
+            result = new byte[(hexlen / 2)];
+            inHex = "0" + inHex;
+        } else {
+            //鍋舵暟
+            result = new byte[(hexlen / 2)];
+        }
+        int j = 0;
+        for (int i = 0; i < hexlen; i += 2) {
+            result[j] = hexToByte(inHex.substring(i, i + 2));
+            j++;
+        }
+        return result;
+    }
+
+
+    /**
+     * Hex瀛楃涓茶浆byte
+     *
+     * @param inHex 寰呰浆鎹㈢殑Hex瀛楃涓�
+     * @return 杞崲鍚庣殑byte
+     */
+    public static byte hexToByte(String inHex) {
+        return (byte) Integer.parseInt(inHex, 16);
+    }
+
+    /**
+     * 瀛楄妭杞崄鍏繘鍒�
+     *
+     * @param b 闇�瑕佽繘琛岃浆鎹㈢殑byte瀛楄妭
+     * @return 杞崲鍚庣殑Hex瀛楃涓�
+     */
+    public static String byteToHex(byte b) {
+        String hex = Integer.toHexString(b & 0xFF);
+        if (hex.length() < 2) {
+            hex = "0" + hex;
+        }
+        return hex.toUpperCase();
+    }
+
+
+    /**
+     * 瀛楄妭鏁扮粍杞�16杩涘埗
+     *
+     * @param bytes 闇�瑕佽浆鎹㈢殑byte鏁扮粍
+     * @return 杞崲鍚庣殑Hex瀛楃涓�
+     */
+    public static String bytesToHex(byte[] bytes) {
+        try {
+            StringBuffer sb = new StringBuffer();
+            for (int i = 0; i < bytes.length; i++) {
+                String hex = Integer.toHexString(bytes[i] & 0xFF);
+                if (hex.length() < 2) {
+                    sb.append(0);
+                }
+                sb.append(hex);
+            }
+            return sb.toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+    public static String byteArrayToHexString(byte[] byteArray) {
+        StringBuilder hexString = new StringBuilder();
+        for (byte b : byteArray) {
+            // 灏嗗瓧鑺傝浆鎹负鏃犵鍙锋暣鏁�
+            int unsignedInt = b & 0xff;
+            // 灏嗘棤绗﹀彿鏁存暟杞崲涓�16杩涘埗瀛楃涓�
+            String hex = Integer.toHexString(unsignedInt);
+            // 濡傛灉瀛楃涓查暱搴﹀皬浜�2锛屽湪鍓嶉潰琛�0
+            if (hex.length() < 2) {
+                hex = "0" + hex;
+            }
+            hexString.append(hex);
+        }
+        return hexString.toString();
+    }
+
+    /**
+     * 瀛楄妭鏁扮粍杞�16杩涘埗 涓嶅湪鏈熬娣诲姞0
+     *
+     * @param bytes 闇�瑕佽浆鎹㈢殑byte鏁扮粍
+     * @return 杞崲鍚庣殑Hex瀛楃涓�
+     */
+    public static String bytesToHexNoAddZero(byte[] bytes) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < bytes.length; i++) {
+            String hex = Integer.toHexString(bytes[i] & 0xFF);
+            sb.append(hex);
+        }
+        return sb.toString();
+    }
+
+
+    /**
+     * 灏� 4瀛楄妭鐨�16杩涘埗瀛楃涓诧紝杞崲涓�32浣嶅甫绗﹀彿鐨勫崄杩涘埗娴偣鍨�
+     *
+     * @param str 4瀛楄妭 16杩涘埗瀛楃
+     * @return
+     */
+    public static float hexToFloat(String str) {
+        return Float.intBitsToFloat(new BigInteger(str, 16).intValue());
+    }
+
+    /**
+     * 灏嗗甫绗﹀彿鐨�32浣嶆诞鐐规暟瑁呮崲涓�16杩涘埗
+     *
+     * @param value
+     * @return
+     */
+    public static String folatToHexString(Float value) {
+        return Integer.toHexString(Float.floatToIntBits(value));
+    }
+
+    /**
+     * 鍗佽繘鍒惰浆16杩涘埗
+     *
+     * @param number
+     * @return
+     */
+    public static String get10to16(int number) {
+        return Integer.toHexString(number);
+    }
+
+    /**
+     * 鍗佽繘鍒惰浆16杩涘埗 琛ラ綈鍋舵暟 楂樹綅鍦ㄥ墠浣庝綅鍦ㄥ悗
+     *
+     * @param number
+     * @return
+     */
+    public static String get10to16CompleteHex(int number) {
+        String hex = Integer.toHexString(number);
+        if (hex.length() % 2 == 0) {
+            return hex;
+        } else {
+            return "0" + hex;
+        }
+    }
+
+    /**
+     * 鍗佽繘鍒惰浆16杩涘埗浣庝綅鍦ㄥ墠楂樹綅鍦ㄥ悗
+     *
+     * @param number 鍗佽繘鍒舵暟
+     * @param length 琛ヨ冻澶氬皯浣�
+     * @return
+     */
+    public static String get10to16LowHigh(int number, int length) {
+        String str = "";
+        try {
+            str = Integer.toHexString(number);
+            str = getHexToLenght(str, length);
+            str = spaceHex(str);
+            str = HighLowHex(str);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return str;
+    }
+
+    /**
+     * 16杩涘埗杞�10杩涘埗楂樹綆浣嶈浆鎹�
+     *
+     * @param hex
+     * @return
+     */
+    public static int get16to10LowHigh(String hex) {
+        try {
+            String str = "";
+            str = spaceHex(hex);
+            str = HighLowHex(str);
+            return Integer.parseInt(str, 16);
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        }
+        return 0;
+    }
+
+
+    /**
+     * 杩斿洖鐗瑰畾闀垮害鐨�16杩涘埗瀛楃涓�
+     *
+     * @param data
+     * @param length
+     * @return
+     */
+    public static String getHexToLenght(String data, int length) {
+        StringBuffer stringBuilder = new StringBuffer(data);
+        for (int i = 0; i < length - data.length(); i++) {
+            stringBuilder.insert(0, "0");
+        }
+        return stringBuilder.toString();
+    }
+
+    /**
+     * 鍗佸叚杩涘埗鏁伴殧绌轰綅
+     *
+     * @param str
+     * @return
+     */
+    public static String spaceHex(String str) {
+        char[] array = str.toCharArray();
+        if (str.length() <= 2) return str;
+        StringBuffer bufferHex = new StringBuffer();
+        for (int i = 0; i < array.length; i++) {
+            int start = i + 1;
+            if (start % 2 == 0) {
+                bufferHex.append(array[i]).append(" ");
+            } else {
+                bufferHex.append(array[i]);
+            }
+        }
+        return bufferHex.toString();
+    }
+
+    /**
+     * 楂樹綅16杩涘埗杞綆浣�
+     *
+     * @param str
+     * @return
+     */
+    private static String HighLowHex(String str) {
+        if (str.trim().length() <= 2) return str;
+        List<String> list = Arrays.asList(str.split(" "));
+        Collections.reverse(list);
+        StringBuffer stringBuffer = new StringBuffer();
+        for (String string : list) {
+            stringBuffer.append(string);
+        }
+        return stringBuffer.toString();
+    }
+
+    /**
+     * @param hex
+     * @return
+     */
+    public static int get16to10(String hex) {
+        int x = 0;
+        try {
+            x = Integer.parseInt(hex, 16);
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+        }
+        return x;
+    }
+}
diff --git a/easysocket/src/main/java/com/easysocket/utils/LogUtil.java b/easysocket/src/main/java/com/easysocket/utils/LogUtil.java
new file mode 100644
index 0000000..df549bf
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/utils/LogUtil.java
@@ -0,0 +1,87 @@
+package com.easysocket.utils;
+import android.util.Log;
+
+import com.easysocket.EasySocket;
+
+
+public class LogUtil {
+    public static final String LOGTAG = "easysocket";
+    public static boolean debugEnabled = EasySocket.getInstance().getDefOptions().isDebug();
+
+    public LogUtil() {
+    }
+
+    private static String getDebugInfo() {
+        Throwable stack = new Throwable().fillInStackTrace();
+        StackTraceElement[] trace = stack.getStackTrace();
+        int n = 2;
+        return trace[n].getClassName() + " " + trace[n].getMethodName() + "()" + ":" + trace[n].getLineNumber() +
+                " ";
+    }
+
+    private static String getLogInfoByArray(String[] infos) {
+        StringBuilder sb = new StringBuilder();
+        for (String info : infos) {
+            sb.append(info);
+            sb.append(" ");
+        }
+        return sb.toString();
+    }
+
+    public static void i(String... s) {
+        if (debugEnabled) {
+            i(LOGTAG, getDebugInfo() + getLogInfoByArray(s));
+        }
+    }
+
+    public static void e(Throwable tr) {
+        if (debugEnabled) {
+            Log.e(LOGTAG, getDebugInfo() ,tr);
+        }
+    }
+
+    public static void e(String... s) {
+        if (debugEnabled) {
+            e(LOGTAG, getDebugInfo() + getLogInfoByArray(s));
+        }
+    }
+
+    public static void d(String... s) {
+        if (debugEnabled) {
+            d(LOGTAG, getDebugInfo() + getLogInfoByArray(s));
+        }
+    }
+
+    public static void v(String... s) {
+        if (debugEnabled) {
+            v(LOGTAG, getDebugInfo() + getLogInfoByArray(s));
+        }
+    }
+
+    public static void w(String... s) {
+        if (debugEnabled) {
+            w(LOGTAG, getDebugInfo() + getLogInfoByArray(s));
+        }
+    }
+
+    private static void i(String name, String log) {
+        System.out.println(name + "锛�" + log);
+    }
+
+    private static void d(String name, String log) {
+        System.out.println(name + "锛�" + log);
+    }
+
+    private static void v(String name, String log) {
+        System.out.println(name + "锛�" + log);
+    }
+
+    private static void e(String name, String log) {
+        System.err.println(name + "锛�" + log);
+    }
+
+    private static void w(String name, String log) {
+        System.err.println(name + "锛�" + log);
+    }
+
+}
diff --git a/easysocket/src/main/java/com/easysocket/utils/Utils.java b/easysocket/src/main/java/com/easysocket/utils/Utils.java
new file mode 100644
index 0000000..10d97c5
--- /dev/null
+++ b/easysocket/src/main/java/com/easysocket/utils/Utils.java
@@ -0,0 +1,149 @@
+package com.easysocket.utils;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Handler;
+import android.os.Looper;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.Random;
+
+/**
+ * Created by LXR ON 2018/8/30.
+ */
+public class Utils {
+
+    /**
+     * 鑾峰彇娉涘瀷鍙傛暟鐨勭被鍨�
+     *
+     * @param <T>
+     * @return
+     */
+    public static <T> Type findGenericityType(Class<T> cls) {
+        Type genType = cls.getGenericSuperclass(); //杩斿洖鐩存帴缁ф壙鐨勭埗绫伙紙鍖呭惈娉涘瀷鍙傛暟锛夌被鍨�,濡傛灉鏈夋硾鍨婽,涔熻鍖呮嫭杩涘幓
+        //getActualTypeArguments 鑾峰彇娉涘瀷涓殑瀹為檯绫诲瀷锛屾瘮濡侻ap<Sting,String>涓殑String绫诲瀷
+        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
+        Type type = params[0]; //娉涘瀷鐨勫疄闄呯被鍨�
+        Type finalNeedType;
+        if (type instanceof ParameterizedType) { //浜岀骇娉涘瀷锛岃繖閲屽氨澶勭悊鏈�澶氫簩绾у惂锛屽舰濡� A<B<T>>锛屼袱涓�<>
+            finalNeedType = ((ParameterizedType) type).getActualTypeArguments()[0];
+        } else { // 涓�绾ф硾鍨嬶紝褰㈠A<T>
+            finalNeedType = type;
+        }
+        //濡傛灉娉涘瀷绫诲瀷杩樻槸鍙橀噺绫诲瀷锛屾瘮濡俆銆乂涔嬬被鐨勶紝浠h〃娌℃湁濉啓娉涘瀷鍙傛暟
+        if (finalNeedType instanceof TypeVariable) throw new IllegalStateException("娌℃湁濉啓娉涘瀷鍙傛暟");
+        return finalNeedType;
+    }
+
+    /**
+     * 瀛楃涓叉槸鍚︿负绌�
+     *
+     * @param str
+     * @return
+     */
+    public static boolean isStringEmpty(String str) {
+        return str == null || str.trim().length() == 0;
+    }
+
+    /**
+     * 鐢熸垚闅忔満瀛楃涓�
+     *
+     * @param length
+     * @return
+     */
+    public static String getRandomChar(int length) {
+        char[] chr = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
+        Random random = new Random();
+        StringBuffer buffer = new StringBuffer();
+        for (int i = 0; i < length; i++) {
+            buffer.append(chr[random.nextInt(36)]);
+        }
+        return buffer.toString();
+    }
+
+
+    /**
+     * 鑾峰彇handler瀵硅薄
+     *
+     * @param isMainHandler 鏄惁涓轰富绾跨▼鐨刪andler锛屼负false鏃惰繑鍥炵殑鏄綋鍓嶇嚎绋媓andler
+     * @return
+     */
+    public static Handler getHandler(boolean isMainHandler) {
+        Handler handler;
+        if (isMainHandler) {
+            handler = new Handler(Looper.getMainLooper());
+        } else {
+            Looper.prepare();
+            handler = new Handler();
+        }
+        return handler;
+    }
+
+    /**
+     * 鐫$湢澶氬皯姣
+     *
+     * @param milliSecond 姣
+     */
+    public static void sleep(long milliSecond) {
+        try {
+            Thread.sleep(milliSecond);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 闈炵┖妫�鏌�
+     *
+     * @param object
+     * @param emsg
+     * @throws
+     */
+    public static void checkNotNull(Object object, String emsg) {
+        try {
+            if (object == null) {
+                throw new Exception(emsg);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void throwNotNull(Object object, String emsg) throws Exception {
+        if (object == null) {
+            throw new Exception(emsg);
+        }
+    }
+
+    // 鍒ゆ柇鏄惁杩炴帴缃戠粶
+    public static boolean isNetConnected(Context context) {
+        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo info = cm.getActiveNetworkInfo();
+        return info != null && info.isConnected();
+    }
+
+    /**
+     * 鎷兼帴涓や釜byte[]
+     *
+     * @param
+     * @param
+     * @return
+     */
+    public static byte[] concatBytes(byte[] bt1, byte[] bt2) {
+        if (bt1 == null) {
+            return bt2;
+        }
+        if (bt2 == null) {
+            return bt1;
+        }
+        byte[] bt3 = new byte[bt1.length + bt2.length];
+        System.arraycopy(bt1, 0, bt3, 0, bt1.length);
+        System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
+        return bt3;
+    }
+
+}
diff --git a/settings.gradle b/settings.gradle
index 6abf7c7..a91ce91 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -15,4 +15,4 @@
     }
 }
 rootProject.name = "chargeQh"
-include ':app',':pickerviewlibrary'
+include ':app',':pickerviewlibrary',':easysocket'

--
Gitblit v1.8.0