package com.socket; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import com.google.gson.Gson; import com.mode.BattRTData; import com.mode.BattTestParam; import com.mode.BattTestRtData; import com.mode.DeviceState; import com.mode.ServiceModel; import com.service.MyInteractionService; import com.util.Com; import com.util.ComFn; import com.util.Ecb_Aes; import com.util.FBS_Cmd; import com.util.FBS_ComBase; import com.util.FBS_ComBuf; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Date; public class MySocketClientThread extends Thread{ public static final String TAG = "MySocketClientThread"; private String server_ip; //服务器ip地址 private int server_port = 6666; //设备屏监听端口 private BattRTData battData; //电池实时数据 private BattTestParam testParam; //电池测试参数 private BattTestRtData testRtData; //电池测试数据 private FBS_Cmd m_FBS_Cmd = new FBS_Cmd(); private ByteBuffer bytebuffer_for_socket_RX = ByteBuffer.allocate(1500); public Handler mHandler = null; public static Socket socket = null; private Date lastConTime; //上一次通讯成功的时间 private boolean thread_run_flag = true; public boolean isRuning = false; ServiceModel returnmodel = new ServiceModel(); private static MySocketClientThread thread ; public static MyInteractionService service = null; private MySocketClientThread(String server_ip){ this.server_ip = server_ip; battData = new BattRTData(); testParam = new BattTestParam(); testRtData = new BattTestRtData(); } public static MySocketClientThread createThread(String server_ip, MyInteractionService service){ MySocketClientThread.service = service; if(thread == null){ thread = new MySocketClientThread(server_ip); } return thread; } //获取当前正在运行的线程 public static MySocketClientThread getNowThread(){ return thread; } /*********************************************************************************************/ public void run() { //初始化消息循环队列,需要在Handler创建之前 Looper.prepare(); isRuning = true; mHandler = new Handler() { public void handleMessage(Message msg) { ServiceModel model = (ServiceModel)msg.obj; try { if(null != model.handler) { ServiceModel remodel = new ServiceModel(); remodel.cmd = model.cmd; if(true == SocketComm(createByteBuffer(model), remodel)) { remodel.code = 1; remodel.cmd = m_FBS_Cmd.CMD; //--------------- 新建消息与句柄 ----------------- Handler handler = model.handler; Message toMain = handler.obtainMessage(); toMain.obj = remodel; handler.sendMessage(toMain); //----------------------------------------------- sleep(100); }else{ remodel.code = 0; //--------------- 新建消息与句柄 ----------------- Handler handler = model.handler; Message toMain = handler.obtainMessage(); toMain.obj = remodel; handler.sendMessage(toMain); } } } catch (InterruptedException e) { e.printStackTrace(); } } }; Log.e(TAG, "Loop start at "+ Com.getDateTimeFormat(new Date(),Com.DTF_YMDhms) ); //启动子线程消息循环队列 Looper.loop(); isRuning = false; Log.e(TAG, "Loop stop at "+ Com.getDateTimeFormat(new Date(),Com.DTF_YMDhms) ); if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 向指定的socket通道发送数据,以及接收数据 * @return */ public boolean SocketComm(ByteBuffer byteBuffer,ServiceModel model) { boolean res_t = false; InputStream in = null; OutputStream out = null; try { // socket = new Socket(); // SocketAddress socAddress = new InetSocketAddress(server_ip, server_port); // socket.connect(socAddress, 2000); if(socket == null || socket.isClosed()){ Log.e(TAG, "SocketComm:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " ); reConnectDevice(); } if(this.socket != null) { in = this.socket.getInputStream(); out = this.socket.getOutputStream(); //----------------- clear rx buff for tcp resend packet ----------------// byte[] rx_buf_t = new byte[1024]; //----------------------------------------------------------------------// bytebuffer_for_socket_RX.order(ByteOrder.LITTLE_ENDIAN); bytebuffer_for_socket_RX.clear(); //--------------------- socket write -----------------------------------// //--------------------- socket write -----------------------------------// boolean aes_en = false; byte[] plain_tx_t = makeCommBuf(model.cmd, byteBuffer, aes_en); byte[] cipher_tx_t = new byte[plain_tx_t.length]; Ecb_Aes my_aes = new Ecb_Aes(); my_aes.ecb_encrypt(plain_tx_t, cipher_tx_t, plain_tx_t.length); Date d1 = new Date(); //=====================================================================// /* for(int n=0; n<3; n++) { out.write(b); out.flush(); //-----------------------------------------------------------------// try { while(true) { int rx_len_t = in.read(rx_buf_t); if(rx_len_t > 0) { if((bytebuffer_for_socket_RX.position()+rx_len_t) < (bytebuffer_for_socket_RX.capacity()-16)) { bytebuffer_for_socket_RX.put(rx_buf_t, 0, rx_len_t); } } if(bytebuffer_for_socket_RX.position() > 8) { break; } } } catch (SocketTimeoutException soe) { //soe.printStackTrace(); } //-----------------------------------------------------------------// } //=====================================================================// */ int rx_read_time_out = 0; //int rx_len = 0; System.out.println("数据长度" + plain_tx_t.length + "\t发送数据:" + ComFn.bytesToHexString(plain_tx_t, plain_tx_t.length)); out.write(plain_tx_t); out.flush(); while(true) { if(in.available() > 0) { rx_read_time_out = 0; int rx_len_t = in.read(rx_buf_t); if((bytebuffer_for_socket_RX.position()+rx_len_t) < (bytebuffer_for_socket_RX.capacity()-1)) { bytebuffer_for_socket_RX.put(rx_buf_t, 0, rx_len_t); } //bytebuffer_for_socket_RX.put((byte)in.read()); } else { rx_read_time_out++; if((bytebuffer_for_socket_RX.position() >= 18) && (rx_read_time_out>10)){ // res = true; break; } if(rx_read_time_out > 300) { break; } } Thread.sleep(10); } bytebuffer_for_socket_RX.flip(); Date d2 = new Date(); long comm_tms = (d2.getTime() - d1.getTime()); if(comm_tms < 200) { Thread.sleep(200 - comm_tms); } /* System.out.println(this.getName() + " dev_id: " + m_StatAndParam.dev_id + " d2-d1:" + (comm_tms)+"ms" + " rx_len:" + bytebuffer_for_socket_RX.limit() + " tx_count:" + m_FBS_VCData.m_SysState.CommCount + " rx_err_sum:" + m_FBS_VCData.m_SysState.ErrCommCount + " rx_err_count:" + rx_errcount_for_live_of_thread + Com.getNowTimeWithAt()); */ byte[] cipher_buf = new byte[bytebuffer_for_socket_RX.limit()]; byte[] plain_buf = new byte[bytebuffer_for_socket_RX.limit()]; bytebuffer_for_socket_RX.get(cipher_buf); my_aes.ecb_decrypt(cipher_buf, plain_buf, cipher_buf.length); System.err.println("数据长度"+cipher_buf.length+"\t返回数据:"+ ComFn.bytesToHexString(cipher_buf, cipher_buf.length)); //Log.e(TAG, "SocketComm: "+ComFn.bytesToHexString(plain_buf, plain_buf.length)); if(true == getDataFromCommBuf(model,cipher_buf)) { res_t = true; model.code = 1; } else { res_t = false; model.code = 0; } thread_run_flag = true; } else { //System.out.println(this.getName() + "-------socket 异常关闭-------" + Com.getNowTimeWithAt()); thread_run_flag = false; } } catch (IOException | InterruptedException e) { model.code = 0; thread_run_flag = false; } finally { if(!thread_run_flag){ reConnectDevice(); } } return res_t; } /** * 根据指定的命令构造byteBuffer * @return */ public ByteBuffer createByteBuffer(ServiceModel model){ ByteBuffer buffer = ByteBuffer.allocate(0); if(FBS_ComBase.CMD_CREATENEWBATT == model.cmd || FBS_ComBase.CMD_CHANGEBATT == model.cmd || FBS_ComBase.CMD_DELETENOWBATT == model.cmd ){ //新建电池组/切换电池组/删除电池组 testParam.battName = model.msg; buffer = testParam.getNewBattByteBuffer(); }else if(FBS_ComBase.CMD_SETDISCHARGEPARAM == model.cmd){ Gson gson = new Gson(); BattTestParam param = gson.fromJson(model.msg,BattTestParam.class); buffer = param.getByteBuffer(); }else if(FBS_ComBase.CMD_RETURNMAIN == model.cmd){ buffer = ByteBuffer.allocate(1); buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.position(0); buffer.put(FBS_ComBase.changeIntToByte(Integer.parseInt(model.msg))); buffer.flip(); } return buffer; } /*********************************************************************************************/ public byte[] makeCommBuf(final int cmd, ByteBuffer bf, boolean aes_en) { ByteBuffer bbf = FBS_ComBuf.makeFbs9100CommBuf(0xFF, cmd, bf, aes_en); byte byte_rest[] = new byte[bbf.limit()]; bbf.get(byte_rest); return byte_rest; } /*********************************************************************************************/ /** * 重新连接设备 */ public boolean reConnectDevice(){ boolean flag = false; if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } try { socket = new Socket(); SocketAddress socAddress = new InetSocketAddress(server_ip, this.server_port); socket.connect(socAddress, 2000); ServiceModel temp = new ServiceModel(); temp.cmd = FBS_ComBase.CMD_ENTERMACHINECONTROL; SocketComm(ByteBuffer.allocate(0),temp); //进入上位机控制 flag = true; } catch (IOException e) { e.printStackTrace(); } return flag; } /*********************************************************************************************/ public Boolean getDataFromCommBuf(ServiceModel model ,final byte[] bytes) { returnmodel = new ServiceModel(); boolean isSuccess = false; ByteBuffer bf = ByteBuffer.allocate(bytes.length); bf.order(ByteOrder.LITTLE_ENDIAN); bf.put(bytes); bf.flip(); String msg = ""; if(true == m_FBS_Cmd.putByteBuffer(bf)) { model.errcode = m_FBS_Cmd.RecState; model.alarmcode = m_FBS_Cmd.Alarm; lastConTime = new Date(); //--------------------- 心跳包测试 ---------------------------------- if(FBS_ComBase.CMD_HEARTBEAT == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { byte[] b = new byte[bf.limit()]; bf.get(b); try { DeviceState deviceState = new DeviceState(m_FBS_Cmd.WorkState,new String(b,"utf-8")); model.setData(deviceState); System.out.println("当前电池组是:"+new String(b,"utf-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } isSuccess = true; //System.out.println("获取心跳包成功"); } } //--------------------- 新建电池组 ---------------------------------- else if(FBS_ComBase.CMD_CREATENEWBATT == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; //System.out.println("新建电池组成功"); } } //--------------------- 切换电池组 ---------------------------------- else if(FBS_ComBase.CMD_CHANGEBATT == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; Log.e(TAG, "getDataFromCommBuf: 切换电池组成功"); } } //--------------------- 删除电池组 ---------------------------------- else if(FBS_ComBase.CMD_DELETENOWBATT == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; //System.out.println("删除电池组成功"); } } //--------------------- 获取单体数据 ---------------------------------------------- else if(FBS_ComBase.CMD_GETBATTDATA == m_FBS_Cmd.CMD) { System.err.println("获取单体数据"); if(battData.putByteBuffer(bf, m_FBS_Cmd.ByteLen-m_FBS_Cmd.BYTE_LEN)) { //System.out.println("获取单体数据成功"); isSuccess = true; model.setData(battData); } } //--------------------- 获取放电参数 ---------------------------------------------- else if(FBS_ComBase.CMD_GETDISCHARGEPARAM == m_FBS_Cmd.CMD) { Log.e(TAG, "getDataFromCommBuf: 获取放电参数" ); if(testParam.putByteBuffer(bf)) { System.out.println("获取放电参数成功"); //System.out.println(testParam); isSuccess = true; model.setData(testParam); } } //---------------------- 设置放电参数 -------------------------------------------------- else if(FBS_ComBase.CMD_SETDISCHARGEPARAM == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; //System.out.println("设置参数成功"); } } //--------------------- 启动放电 ---------------------------------- else if(FBS_ComBase.CMD_STARTDISCHARGE == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; //System.out.println("启动放电成功"); } } //--------------------- 放电暂停 ---------------------------------- else if(FBS_ComBase.CMD_PAUSEDISCHARGE == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; //System.out.println("暂停放电成功"); } } //--------------------- 停止放电 ---------------------------------- else if(FBS_ComBase.CMD_STOPDISCHARGE == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; //System.out.println("停止放电成功"); } } //--------------------- 获取放电数据 ---------------------------------- else if(FBS_ComBase.CMD_GETDISCHARGEDATA == m_FBS_Cmd.CMD) { if(testRtData.putByteBuffer(bf)) { isSuccess = true; model.setData(testRtData); //System.out.println("获取放电数据成功"+testRtData); } } //--------------------- 启动充电 ---------------------------------- else if(FBS_ComBase.CMD_STARTCHARGE== m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; //System.out.println("启动充电成功"); } } //--------------------- 暂停充电 ---------------------------------- else if(FBS_ComBase.CMD_PAUSECHARGE== m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; // System.out.println("暂停充电成功"); } } //--------------------- 停止充电 ---------------------------------- else if(FBS_ComBase.CMD_STOPCHARGE== m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; //System.out.println("停止充电成功"); } } //--------------------- 获取充电数据 ---------------------------------- else if(FBS_ComBase.CMD_GETCHARGEDATA == m_FBS_Cmd.CMD) { if(testRtData.putByteBuffer(bf)) { isSuccess = true; model.setData(testRtData); //System.out.println("获取充电数据成功"+testRtData); } } //--------------------- 清除告警 ---------------------------------- else if(FBS_ComBase.CMD_CLEARALARM == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; System.out.println("清除告警成功"); } } //--------------------- 进入 Android控制 ---------------------------------- else if(FBS_ComBase.CMD_ENTERMACHINECONTROL == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; System.out.println("进入Android模式成功"); } } //--------------------- 进入界面同步切换 ---------------------------------- else if(FBS_ComBase.CMD_RETURNMAIN == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; System.out.println("切换界面成功"); } } //--------------------- 退出上位机控制 ---------------------------------- else if(FBS_ComBase.CMD_EXITMACHINECONTROL == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; System.out.println("退出上位机控制"); } } //--------------------- 控制活化(启动/停止/暂停) ---------------------------------- else if(FBS_ComBase.CMD_STARTHHTEST == m_FBS_Cmd.CMD || FBS_ComBase.CMD_PAUSEHHTEST == m_FBS_Cmd.CMD || FBS_ComBase.CMD_STOPHHTEST == m_FBS_Cmd.CMD) { if(FBS_ComBase.RETURN_SUCCESS == m_FBS_Cmd.RecState) { isSuccess = true; System.out.println("启动/停止/暂停活化测试成功"); } } } return isSuccess; } public boolean setUpDeviceIp(String server_ip){ boolean flag = false; if(this.socket == null){ flag = reConnectDevice(); }else{ synchronized (socket){ if (this.server_ip != null && server_ip.length() > 0){ this.server_ip = server_ip; flag = reConnectDevice(); } } } return false; } //关闭socket连接 public void closeConn(){ if(this.socket != null){ try { this.socket.close(); } catch (IOException e) { e.printStackTrace(); } } } //测试当前ip是否可以连接 public boolean testSockConn(String server_ip){ boolean flag = false; Socket socket1 = null; try { socket1 = new Socket(); Log.e(TAG, "testSockConn: "+server_ip ); SocketAddress socAddress = new InetSocketAddress(server_ip, this.server_port); socket1.connect(socAddress, 3000); flag = true; } catch (IOException e) { e.printStackTrace(); } finally{ if(socket1 != null){ try { socket1.close(); } catch (IOException e) { e.printStackTrace(); } } } return flag; } }