public class TcpLongSocket {
public static final String TAG = "TcpLongSocket";
public static String HOST = "172";
public static int PORT = 44023;
private ReadThread mReadThread;//接收消息线程
private InitSocketThread mInitSocketThread;//初始化线程,用来连接服务器
private Socket mSocket;
private Handler sgameHandler;
private boolean isReceiveMessage = false;//用来决定是否接收数据
private ExecutorService cachedThreadPool;//线程池,用来发送消息
public TcpLongSocket() {
}
public void initTcpLongSocket(String host, int port, Handler sgameHandler) {
LogUtil.e(TAG, "initTcpLongSocket");
HOST = host;
PORT = port;
isReceiveMessage = true;
cachedThreadPool = Executors.newCachedThreadPool();
this.sgameHandler = sgameHandler;
mInitSocketThread = new InitSocketThread();
mInitSocketThread.start();
}
class InitSocketThread extends Thread {
@Override
public void run() {
super.run();
try {
mSocket = new Socket(HOST, PORT);
LogUtil.e(TAG, "开始连接服务器");
mReadThread = new ReadThread();
mReadThread.start();
while (connectJudge) {
if (isSocketConnect()) {
connectJudge = false;
if (onConnectListener != null) {
onConnectListener.onConnect(true);
}
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
LogUtil.e(TAG + "----------------", e.toString());
} catch (IOException e) {
e.printStackTrace();
LogUtil.e(TAG + "----------------", e.toString());
}
}
}
public boolean sendMsg(final byte[] req) {
if (null == mSocket) {
return false;
}
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
if (!mSocket.isClosed() && !mSocket.isOutputShutdown()) {
LogUtil.e(TAG, "--------------发送的信息------------------" + new String(req));
OutputStream os = mSocket.getOutputStream();
os.write(req);
os.flush();
LogUtil.e(TAG, "--------------发送的信息-------发送成功-----------");
LogUtil.e(TAG, "--------------发送的信息-------发送成功-------req.length----" + req.length);
}
} catch (IOException e) {
e.printStackTrace();
LogUtil.e(TAG, "--------------发送的信息------------ e.printStackTrace();------");
}
}
});
return true;
}
/**
* 接收消息
*/
class ReadThread extends Thread {
public void release() {
releaseLastSocket();
}
@Override
public void run() {
super.run();
if (null != mSocket) {
try {
InputStream is = mSocket.getInputStream();
byte[] buffer = new byte[1024 * 4];
int length = 0;
while (!mSocket.isClosed() && !mSocket.isInputShutdown()
&& isReceiveMessage && ((length = is.read(buffer)) != -1)) {
if (length > 4) {
String line = new String(Arrays.copyOf(buffer,
length)).trim();
Log.e(TAG, "接收的消息:" + line);
//收到服务器过来的消息,就通过Broadcast发送出去
transpond(buffer, length);
}
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
if (onConnectListener != null) {
onConnectListener.onConnect(false);
}
}
}
}
private boolean connectJudge = true;
public interface OnConnectListener {
void onConnect(boolean isConnect);
}
OnConnectListener onConnectListener;
public void setOnConnectListener(OnConnectListener onConnectListener) {
this.onConnectListener = onConnectListener;
}
private void transpond(byte[] buffer, int length) {
byte[] bytes = Arrays.copyOf(buffer, length);
Log.e(TAG, "transpond 接收的消息 bytes:" + new String(bytes));
Message message = sgameHandler.obtainMessage();
message.obj = bytes;
sgameHandler.sendMessage(message);
}
/**
* 关闭socket
*/
private void releaseLastSocket() {
try {
connectJudge = true;
if (null != mSocket) {
if (!mSocket.isClosed()) {
mSocket.close();
}
mSocket = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 关闭所有的东西,包括socket、线程等
*/
public void colseSocketTcp() {
LogUtil.e(TAG, "关闭tcp");
releaseLastSocket();
if (mInitSocketThread != null) {
mInitSocketThread.interrupt();
}
if (mReadThread != null) {
mReadThread.interrupt();
}
isReceiveMessage = false;
}
/**
* socket是否已经链接
*
* @return
*/
public boolean isSocketConnect() {
if (mSocket != null) {
return mSocket.isConnected();
}
return false;
}
/**
* 重新链接
*
* @param host
* @param port
*/
public void resetSocketConnect(String host, int port, Handler sgameHandler) {
colseSocketTcp();
HOST = host;
PORT = port;
this.sgameHandler = sgameHandler;
isReceiveMessage = true;
cachedThreadPool = Executors.newCachedThreadPool();
mInitSocketThread = new InitSocketThread();
mInitSocketThread.start();
}
}具体使用
public class OrderManagerService extends Service {
public static final String TAG = "OrderManagerService";
public static String orderManagerServiceHost;
public static int orderManagerServicePort;
private TcpLongSocket tcpLongSocket;
private AtomicBoolean atomicBoolean = new AtomicBoolean(false);
private RemoteCallbackList<IOnReceiveBytesListener> iOnReceiveBytesListenerRemoteCallbackList = new RemoteCallbackList<>();
private MyHandler myHandler = new MyHandler();
@Override
public void onCreate() {
super.onCreate();
LogUtil.i(TAG, "onCreate");
if (!TextUtils.isEmpty(orderManagerServiceHost) && orderManagerServicePort != 0) {
tcpLongSocket = new TcpLongSocket();
tcpLongSocket.initTcpLongSocket(orderManagerServiceHost, orderManagerServicePort, myHandler);
}
}
private Binder binder = new IOrderManager.Stub() {
@Override
public void initTcp(String host, int port) throws RemoteException {
LogUtil.i(TAG, "initTcp host:" + host);
LogUtil.i(TAG, "initTcp port:" + port);
connectService(host, port);
}
@Override
public void sendByte(byte[] bytes) throws RemoteException {
}
@Override
public void sendGoodsInfo(GoodsDetail netbarCharge, List<GoodsDetail> goodsDetailList, int payType) throws RemoteException {
LogUtil.i(TAG, "sendGoodsInfo netbarCharge:" + netbarCharge.toString());
LogUtil.i(TAG, "sendGoodsInfo goodsDetailList:" + goodsDetailList.toString());
LogUtil.i(TAG, "sendGoodsInfo payType:" + payType);
if (tcpLongSocket != null) {
boolean sendSuccess = tcpLongSocket.sendMsg(OrderUtils.crearGoodsByte(netbarCharge, goodsDetailList, payType));
LogUtil.i(TAG, "---------sendGoodsInfo-------noticeStatus");
if (!sendSuccess) {
noticeStatus(sendSuccess);
}
}
}
@Override
public void registerOnReceiveBytesListener(IOnReceiveBytesListener listener) throws RemoteException {
boolean register = iOnReceiveBytesListenerRemoteCallbackList.register(listener);
LogUtil.i(TAG, "registerOnReceiveBytesListener:" + register);
}
@Override
public void unRegisterOnReceiveBytesListener(IOnReceiveBytesListener listener) throws RemoteException {
boolean unRegister = iOnReceiveBytesListenerRemoteCallbackList.unregister(listener);
LogUtil.i(TAG, "unRegisterOnReceiveBytesListener:" + unRegister);
}
};
/**
* 链接服务器
*
* @param host
* @param port
*/
private void connectService(String host, int port) {
if (tcpLongSocket == null) {
tcpLongSocket = new TcpLongSocket();
tcpLongSocket.initTcpLongSocket(String.valueOf(host), port, myHandler);
orderManagerServiceHost = host;
orderManagerServicePort = port;
} else {
if (tcpLongSocket.isSocketConnect()) {
if (!host.equals(orderManagerServiceHost)) {
tcpLongSocket.resetSocketConnect(host, port, myHandler);
} else if (port != orderManagerServicePort) {
tcpLongSocket.resetSocketConnect(host, port, myHandler);
} else {
LogUtil.i(TAG, "---------connectService-------noticeStatus");
noticeStatus(true);
}
} else {
tcpLongSocket.resetSocketConnect(host, port, myHandler);
}
}
socketIsConnectingListener();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
LogUtil.i(TAG, "binder:" + binder);
return binder;
}
class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
byte[] bytes = (byte[]) msg.obj;
ReceiveData receiveData = new ReceiveData();
int sIndex = OrderUtils.getSIndex(bytes);
receiveData.setsIndex(sIndex);
LogUtil.i(TAG, "bytes.length:" + bytes.length);
LogUtil.i(TAG, " new String(bytes):" + new String(bytes));
LogUtil.i(TAG, "sIndex:" + sIndex);
LogUtil.i(TAG, "handleMessage new String(bytes):" + new String(bytes));
if (sIndex == OrderUtils.DEFINE_ID_PACK_ORDER_RECY) {
int sPackLen = OrderUtils.getSPackLen(bytes, 4);
LogUtil.i(TAG, "DEFINE_ID_PACK_ORDER_RECY sPackLen:" + sPackLen);
//订单回包数据
String orderRecy = OrderUtils.getReceiveData(bytes, sPackLen, 8);
receiveData.setsPackLen(sPackLen);
receiveData.setsPackData(orderRecy);
} else if (sIndex == OrderUtils.DEFINE_ID_PACK_ORDER_PAY_RECY) {
int sCode = OrderUtils.getSPackLen(bytes, 4);
LogUtil.i(TAG, "DEFINE_ID_PACK_ORDER_PAY_RECY sCode:" + sCode);
int sPackLen = OrderUtils.getSPackLen(bytes, 8);
LogUtil.i(TAG, "DEFINE_ID_PACK_ORDER_PAY_RECY sPackLen:" + sPackLen);
//支付回包
String payRecy = OrderUtils.getReceiveData(bytes, sPackLen, 12);
receiveData.setsCode(sCode);
receiveData.setsPackLen(sPackLen);
receiveData.setsPackData(payRecy);
}
try {
final int n = iOnReceiveBytesListenerRemoteCallbackList.beginBroadcast();
for (int i = 0; i < n; i++) {
IOnReceiveBytesListener iOnDataTransmissionListenerRemoteCallbackList = iOnReceiveBytesListenerRemoteCallbackList.getBroadcastItem(i);
if (iOnDataTransmissionListenerRemoteCallbackList != null) {
LogUtil.i(TAG, "onReceiveBytes:success");
iOnDataTransmissionListenerRemoteCallbackList.onReceiveBytes(receiveData);
} else {
LogUtil.i(TAG, "onReceiveBytes:fail");
}
}
iOnReceiveBytesListenerRemoteCallbackList.finishBroadcast();
} catch (RemoteException e) {
LogUtil.i(TAG, "onReceiveBytes:RemoteException");
e.printStackTrace();
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
LogUtil.i(TAG, "onDestroy");
atomicBoolean.set(true);
if (tcpLongSocket == null) {
tcpLongSocket.colseSocketTcp();
}
}
private void noticeStatus(boolean isSuccessConnect) {
LogUtil.i(TAG, "---------noticeStatus-------isSuccessConnect:" + isSuccessConnect);
try {
final int n = iOnReceiveBytesListenerRemoteCallbackList.beginBroadcast();
for (int i = 0; i < n; i++) {
IOnReceiveBytesListener iOnDataTransmissionListenerRemoteCallbackList = iOnReceiveBytesListenerRemoteCallbackList.getBroadcastItem(i);
if (iOnDataTransmissionListenerRemoteCallbackList != null) {
if (isSuccessConnect) {
LogUtil.i(TAG, "---------noticeStatus-------onSuccessConnect");
iOnDataTransmissionListenerRemoteCallbackList.onSuccessConnect();
} else {
LogUtil.i(TAG, "---------noticeStatus-------onFailConnect");
iOnDataTransmissionListenerRemoteCallbackList.onFailConnect(0);
}
}
}
iOnReceiveBytesListenerRemoteCallbackList.finishBroadcast();
} catch (RemoteException e) {
e.printStackTrace();
}
}
private void socketIsConnectingListener() {
if (tcpLongSocket != null) {
LogUtil.i(TAG, "socketIsConnectingListener");
tcpLongSocket.setOnConnectListener(new TcpLongSocket.OnConnectListener() {
@Override
public void onConnect(boolean isConnect) {
LogUtil.i(TAG, "---------tcpLongSocket.setOnConnectListener-------noticeStatus");
noticeStatus(isConnect);
}
});
}
}
}