工具类
public class MyServerSocket extends Thread { private final static String TAG = "MyServerSocket"; private ServerSocket mServerSocket = null; private int timeout = 30000;//socket搜寻超时时间 private Long timeMax = 10000l;//验证断开链接时间 private Boolean isConnected = false; private int mPort = 12345;//端口号 private Handler mHandler = null;//用来回传到主线程的handler public Map<String, Socket> mOut = new HashMap<>(); public MyServerSocket(int port, Handler handler) { mPort = port; mHandler = handler; } @Override public void run() { getSocked(); } public void getSocked() { try { Log.d(TAG, "开始搜寻tcp"); mServerSocket = new ServerSocket(mPort); Log.d(TAG, "开始搜寻tcp1"); mServerSocket.setReuseAddress(true); // 允许端口重用 Log.d(TAG, "开始搜寻tcp2"); mServerSocket.setSoTimeout(timeout); Log.d(TAG, "开始搜寻tcp3"); Socket mSocket = mServerSocket.accept(); Log.d(TAG, "开始搜寻tcp4"); mSocket.setReuseAddress(true); // 允许端口重用 Log.d(TAG, "开始搜寻tcp5"); mSocket.setSoTimeout(timeout); Log.d(TAG, "开始搜寻tcp6"); Log.d(TAG, "获取到的ip:" + mSocket.getLocalAddress().getHostAddress() + " " + mSocket.getInetAddress().getHostAddress()); if (mOut.get(mSocket.getInetAddress().getHostAddress()) == null || !mOut.get(mSocket.getInetAddress().getHostAddress()).equals(mSocket.getInetAddress().getHostAddress())) { Log.d(TAG, "添加ip:" + mSocket.getInetAddress().getHostAddress()); mOut.put(mSocket.getInetAddress().getHostAddress(), mSocket); } isConnected = true; // writeMsgInternal("### A message from MyServerSocket."); readMsgInternal(); } catch (IOException e) { e.printStackTrace(); isConnected = false; Log.d(TAG, "出错了:" + e.getMessage().toString()); } //Log.i(TAG, "accept success"); mHandler.sendEmptyMessage(MyEnum.MSG_SOCKET_CONNECTOK); Log.d(TAG, "结束了"); } private void readMsgInternal() { Log.d(TAG, "开始搜寻开关ip:" + isConnected); // detection.start(); while (isConnected) { byte[] buffer = new byte[1024]; //循环执行read,用来接收数据。 //数据存在buffer中,count为读取到的数据长度。 try { //等待客户端的连接,Accept会阻塞,直到建立连接, //所以需要放在子线程中运行。 if (mOut != null && mOut.size() > 0) { for (Map.Entry<String, Socket> entry : mOut.entrySet()) { // deteTime=System.currentTimeMillis(); Socket value = entry.getValue(); InputStream mInStream = value.getInputStream(); int count = mInStream.read(buffer); String str = bytesToHex(buffer); Log.d(TAG, "接收到的数据:" + str); Message msg = new Message(); msg.what = MyEnum.MSG_SOCKET_READ; msg.obj = value.getInetAddress().getHostAddress() + "," + str; if (mHandler != null) mHandler.sendMessage(msg); } } } catch (IOException e) { e.printStackTrace(); Log.d(TAG, "接收数据错误:" + e.getMessage().toString()); mHandler.sendEmptyMessage(MyEnum.MSG_SOCKET_ACCEPTFAIL); } } Log.d(TAG, "readMsgInternal:end"); } //发送 private void writeMsgInternal(String msg, String ip) { try { Log.d(TAG, "使用ip:" + ip + " 命令:" + msg); Socket socket = mOut.get(ip); if (socket == null) { return; } OutputStream mOutStream = socket.getOutputStream(); Log.d(TAG, "发送命令:" + msg + " 输出流" + mOutStream); if (msg.length() == 0 || mOutStream == null) { return; } //发送 mOutStream.write(hexStringToBytes(msg)); mOutStream.flush(); } catch (Exception e) { e.printStackTrace(); Log.d(TAG, "发送命令错误:" + e.getMessage().toString()); isConnected = false; } } //发送 public void writeMsg(String str, String ip) { new Thread(new Runnable() { @Override public void run() { writeMsgInternal(str, ip); } }).start(); } //关闭 public void close() { isConnected = false; if (mServerSocket != null) { try { Log.d(TAG, "关闭链接"); mServerSocket.close(); } catch (IOException e) { e.printStackTrace(); } } mServerSocket = null; Log.d(TAG, "关闭结果:" + mServerSocket); for (Map.Entry<String, Socket> entry : mOut.entrySet()) { // deteTime=System.currentTimeMillis(); Socket mSocket = entry.getValue(); if (mSocket != null) { try { mSocket.close(); mSocket = null; } catch (IOException e) { e.printStackTrace(); } } } mOut.clear(); } public static String bytesToHex(byte[] bytes) { StringBuilder hexString = new StringBuilder(); for (byte b : bytes) { String hex = Integer.toHexString(0xFF & b); if (hex.length() == 1) { // 如果是一位的话,要补0 hexString.append('0'); } hexString.append(hex); } return hexString.toString(); } public static byte[] hexStringToBytes(String hexString) { if (hexString == null || hexString.equals("")) { return null; } hexString = hexString.trim(); hexString = hexString.toUpperCase(); int length = hexString.length() / 2; char[] hexChars = hexString.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } public static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } } 传入的handler
Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message msg) { switch (msg.what) { case MyEnum.MSG_SOCKET_READ://接收到的消息 String ss = (String) msg.obj; String[] split = ss.split(","); Log.d(TAG, "接收的mac:" + split[0] + " 命令:" + split[1]); String mac = String.valueOf(split[1]).substring(10, 22); Log.d(TAG, "截取的mac地址:" + lampMAC); if (lampMAC.get(mac) == null) { lampMAC.put(mac, split[0]); } break; case MyEnum.MSG_SOCKET_CONNECTOK://搜寻失败重连 if (myServerSocket != null) { myServerSocket.close(); myServerSocket = null; } try { Thread.sleep(5000); } catch (InterruptedException e) { throw new RuntimeException(e); } myServerSocket = new MyServerSocket(LAMP, handler); Log.d("MyServerSocket", "搜寻失败,重新调用"); myServerSocket.start(); break; case MyEnum.MSG_SOCKET_ACCEPTFAIL://链接断开重连 if (lampMAC.size() > 0 && myServerSocket != null) { for (String key : lampMAC.keySet()) { //发布一次空消息,会自动进行重连,不会出现地址已被占用问题 myServerSocket.writeMsg("00", lampMAC.get(key)); } } break; } return false; } });
初始化
if (myServerSocket == null) { myServerSocket = new MyServerSocket(LAMP, handler); } Log.d("MyServerSocket", "初始化调用"); myServerSocket.start();
保存搜寻到的map集合:
Map<String, String> lampMAC = new HashMap<>();
发送命令
if (lampMAC.size() > 0 && myServerSocket != null) { for (String key : lampMAC.keySet()) { String s ="十六进制命令"; Log.d(TAG, "刷卡开灯命令:" + s); myServerSocket.writeMsg(s, lampMAC.get(key)); } }
传递
public class MyEnum { public static final int MSG_SOCKET_ACCEPTFAIL=10001;//检测错误 public static final int MSG_SOCKET_CONNECTOK=10002;//检测结束 public static final int MSG_SOCKET_READ=10003;//接收到数据,成功 }