工具类
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;//接收到数据,成功
}

6078

被折叠的 条评论
为什么被折叠?



