kopia lustrzana https://github.com/N0BOY/FT8CN
240 wiersze
7.3 KiB
Java
240 wiersze
7.3 KiB
Java
package com.bg7yoz.ft8cn.flex;
|
||
/**
|
||
* 简单封装的Tcp类,用于Flex的命令操作
|
||
* @author BGY70Z
|
||
* @date 2023-03-20
|
||
*/
|
||
|
||
import android.util.Log;
|
||
|
||
import java.io.IOException;
|
||
import java.io.InputStream;
|
||
import java.io.OutputStream;
|
||
import java.net.InetAddress;
|
||
import java.net.Socket;
|
||
import java.net.SocketException;
|
||
import java.util.Arrays;
|
||
import java.util.concurrent.ExecutorService;
|
||
import java.util.concurrent.Executors;
|
||
|
||
public class RadioTcpClient {
|
||
private static final String TAG = "RadioTcpClient";
|
||
private static RadioTcpClient radioTcpClient = null;
|
||
private String ip;
|
||
private int port;
|
||
public static final int MAX_BUFFER_SIZE=1024 * 32;
|
||
|
||
private final ExecutorService sendByteThreadPool = Executors.newCachedThreadPool();
|
||
private final SendByteRunnable sendByteRunnable=new SendByteRunnable(this);
|
||
|
||
public static RadioTcpClient getInstance() {
|
||
if (radioTcpClient == null) {
|
||
synchronized (RadioTcpClient.class) {
|
||
radioTcpClient = new RadioTcpClient();
|
||
}
|
||
}
|
||
return radioTcpClient;
|
||
}
|
||
|
||
private Socket mSocket;
|
||
private OutputStream mOutputStream;
|
||
private InputStream mInputStream;
|
||
|
||
private SocketThread mSocketThread;
|
||
private boolean isStop = false;//thread flag
|
||
|
||
private OnDataReceiveListener onDataReceiveListener = null;
|
||
|
||
public boolean isConnect() {
|
||
boolean flag = false;
|
||
if (mSocket != null) {
|
||
flag = mSocket.isConnected();
|
||
}
|
||
return flag;
|
||
}
|
||
|
||
public void connect(String ip, int port) {
|
||
this.ip = ip;
|
||
this.port = port;
|
||
//mSocketThread = new SocketThread(ip, port);
|
||
mSocketThread = new SocketThread();
|
||
mSocketThread.start();
|
||
}
|
||
|
||
public void disconnect() {
|
||
isStop = true;
|
||
try {
|
||
if (mOutputStream != null) {
|
||
mOutputStream.close();
|
||
}
|
||
|
||
if (mInputStream != null) {
|
||
mInputStream.close();
|
||
}
|
||
|
||
if (mSocket != null) {
|
||
mSocket.close();
|
||
mSocket = null;
|
||
}
|
||
} catch (IOException e) {
|
||
e.printStackTrace();
|
||
}
|
||
if (mSocketThread != null) {
|
||
mSocketThread.interrupt();//not intime destory thread,so need a flag
|
||
}
|
||
}
|
||
|
||
|
||
private class SocketThread extends Thread {
|
||
@Override
|
||
public void run() {
|
||
Log.d(TAG, "TcpSocketThread start...");
|
||
super.run();
|
||
try {
|
||
if (mSocket != null) {
|
||
mSocket.close();
|
||
mSocket = null;
|
||
}
|
||
InetAddress ipAddress = InetAddress.getByName(ip);
|
||
mSocket = new Socket(ipAddress, port);
|
||
//设置不延时发送
|
||
//mSocket.setTcpNoDelay(true);
|
||
//设置输入输出缓冲流大小
|
||
//mSocket.setSendBufferSize(8*1024);
|
||
//mSocket.setReceiveBufferSize(8*1024);
|
||
if (isConnect()) {
|
||
mOutputStream = mSocket.getOutputStream();
|
||
mInputStream = mSocket.getInputStream();
|
||
|
||
|
||
isStop = false;
|
||
connectSuccess();
|
||
}
|
||
/* 此处这样做没什么意义不大,真正的socket未连接还是靠心跳发送,等待服务端回应比较好,一段时间内未回应,则socket未连接成功 */
|
||
else {
|
||
connectFail();
|
||
return;
|
||
}
|
||
|
||
}catch (SocketException e){
|
||
Log.e(TAG,"TCP Connection exception:"+e.getMessage());
|
||
}
|
||
catch (IOException e) {
|
||
connectFail();
|
||
Log.e(TAG, "SocketThread connect io exception = " + e.getMessage());
|
||
e.printStackTrace();
|
||
return;
|
||
}
|
||
int errorCount=0;
|
||
//read ...
|
||
while (isConnect() && !isStop && !isInterrupted()) {
|
||
int size;
|
||
try {
|
||
byte[] buffer = new byte[MAX_BUFFER_SIZE];
|
||
if (mInputStream == null) return;
|
||
size = mInputStream.read(buffer);//null data -1 ,
|
||
if (size > 0) {
|
||
if (onDataReceiveListener != null) {
|
||
byte[] temp = Arrays.copyOf(buffer, size);
|
||
onDataReceiveListener.onDataReceive(temp);
|
||
}
|
||
errorCount =0;
|
||
}else {
|
||
errorCount ++;
|
||
if (errorCount > 10){
|
||
if (onDataReceiveListener!=null){
|
||
onDataReceiveListener.onConnectionClosed();
|
||
}
|
||
}
|
||
}
|
||
|
||
} catch (SocketException e){
|
||
Log.e(TAG,"Tcp Connection exception:"+e.getMessage());
|
||
} catch (IOException e) {
|
||
//uiHandler.sendEmptyMessage(-1);
|
||
Log.e(TAG, "SocketThread read io exception = " + e.getMessage());
|
||
e.printStackTrace();
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void connectFail() {
|
||
if (onDataReceiveListener != null) {
|
||
onDataReceiveListener.onConnectFail();
|
||
}
|
||
}
|
||
|
||
private void connectSuccess() {
|
||
if (onDataReceiveListener != null) {
|
||
onDataReceiveListener.onConnectSuccess();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* send byte[] cmd
|
||
* Exception : android.os.NetworkOnMainThreadException
|
||
*/
|
||
public synchronized void sendByte(final byte[] mBuffer) {
|
||
sendByteRunnable.mBuffer=mBuffer;
|
||
sendByteThreadPool.execute(sendByteRunnable);
|
||
// new Thread(new Runnable() {
|
||
// @Override
|
||
// public void run() {
|
||
// try {
|
||
// if (mOutputStream != null) {
|
||
// mOutputStream.write(mBuffer);
|
||
// mOutputStream.flush();
|
||
// }
|
||
// } catch (IOException e) {
|
||
// e.printStackTrace();
|
||
// }
|
||
// }
|
||
// }).start();
|
||
}
|
||
|
||
private static class SendByteRunnable implements Runnable{
|
||
RadioTcpClient client;
|
||
byte[] mBuffer;
|
||
public SendByteRunnable(RadioTcpClient client) {
|
||
this.client = client;
|
||
}
|
||
|
||
@Override
|
||
public void run() {
|
||
try {
|
||
if (mBuffer==null) return;
|
||
if (client.mOutputStream != null) {
|
||
client.mOutputStream.write(mBuffer);
|
||
client.mOutputStream.flush();
|
||
}
|
||
} catch (IOException e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
}
|
||
|
||
public interface OnDataReceiveListener {
|
||
void onConnectSuccess();
|
||
|
||
void onConnectFail();
|
||
|
||
void onDataReceive(byte[] buffer);
|
||
void onConnectionClosed();
|
||
}
|
||
|
||
public void setOnDataReceiveListener(
|
||
OnDataReceiveListener dataReceiveListener) {
|
||
onDataReceiveListener = dataReceiveListener;
|
||
}
|
||
|
||
public String getIp() {
|
||
return ip;
|
||
}
|
||
|
||
public int getPort() {
|
||
return port;
|
||
}
|
||
}
|