FT8CN/ft8cn/app/src/main/java/com/bg7yoz/ft8cn/flex/RadioTcpClient.java

240 wiersze
7.3 KiB
Java
Czysty Wina Historia

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
}
}