package com.hdl.sdk.socket.client;
|
|
|
|
import com.hdl.sdk.common.utils.ByteUtils;
|
import com.hdl.sdk.common.utils.ThreadToolUtils;
|
import com.hdl.sdk.socket.SocketBoot;
|
import com.hdl.sdk.socket.SocketOptions;
|
import com.hdl.sdk.socket.annotation.ConnectStatus;
|
import com.hdl.sdk.socket.codec.IHandleMessage;
|
import com.hdl.sdk.socket.listener.ConnectStatusListener;
|
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.io.OutputStream;
|
import java.net.InetSocketAddress;
|
import java.net.Socket;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
|
/**
|
* Created by Tong on 2021/9/15.
|
*/
|
public final class TcpClient implements IClient {
|
/*
|
*接收数据的缓冲区
|
*/
|
private final List<Byte> byteList;
|
private final byte[] head = "Topic:".getBytes();
|
|
private SocketOptions socketOptions;
|
|
private final String ip;
|
private final int port;
|
|
private Socket mSocket;
|
|
private byte[] readBuffer;
|
|
private TcpClient(String ip, int port, SocketOptions socketOptions) {
|
this.byteList = new ArrayList<>();
|
this.socketOptions = socketOptions;
|
this.ip = ip;
|
this.port = port;
|
}
|
|
public static SocketBoot init(String ip, int port, SocketOptions options) {
|
return new SocketBoot(new TcpClient(ip, port, options));
|
}
|
|
|
@Override
|
public void connect() throws Exception {
|
mSocket = getSocket();
|
SocketOptions options = getOptions();
|
mSocket.connect(new InetSocketAddress(ip, port));
|
mSocket.setTcpNoDelay(true);
|
mSocket.setReuseAddress(true);
|
mSocket.setKeepAlive(true);
|
readBuffer = new byte[options.getReadMaxBufferSize()];
|
}
|
|
|
@Override
|
public void disconnect() {
|
if (mSocket != null) {
|
try {
|
mSocket.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
|
@Override
|
public boolean isConnect() {
|
if (mSocket == null) {
|
return false;
|
}
|
|
return mSocket.isConnected() && !mSocket.isClosed();
|
}
|
|
|
@Override
|
public synchronized SocketOptions getOptions() {
|
if (socketOptions == null) {
|
socketOptions = new SocketOptions();
|
}
|
return socketOptions;
|
}
|
|
/// <summary>
|
/// 获取内容长度
|
/// </summary>
|
/// <param name="topMsgs"></param>
|
/// <returns></returns>
|
int getLenght(String[] topMsgs)
|
{
|
for (int i = 0; i < topMsgs.length; i++)
|
{
|
String topMsg = topMsgs[i].trim();
|
if (topMsg.startsWith("Length:"))
|
{
|
return Integer.parseInt(topMsg.replace("Length:", ""));
|
}
|
}
|
//找不到长度
|
return -1;
|
}
|
|
/// <summary>
|
/// 获取主题
|
/// </summary>
|
/// <param name="topMsgs"></param>
|
/// <returns></returns>
|
private String getTopic(String[] topMsgs)
|
{
|
for (int i = 0; i < topMsgs.length; i++)
|
{
|
String topMsg = topMsgs[i].trim();
|
if (topMsg.startsWith("Topic:"))
|
{
|
return topMsg.replace("Topic:", "");
|
}
|
}
|
//找不到主题
|
return null;
|
}
|
|
/**
|
* 获取数据的开始位置
|
* @param arrayList 接收到的所有数据
|
* @return 数据位的开始索引
|
*/
|
int getDataIndex(List<Byte> arrayList)
|
{
|
byte r = (byte)'\r';
|
byte n = (byte)'\n';
|
for (int i = 0; i < arrayList.size(); i++)
|
{
|
//找出数据内容前面的两个换行
|
if (3 <= i && arrayList.get(i - 3) == r && arrayList.get(i - 2) == n && arrayList.get(i - 1) == r && arrayList.get(i) == n)
|
{
|
//剩余的数据
|
return i + 1;
|
}
|
}
|
return -1;
|
}
|
|
void initReceiveData(List<Byte> list) {
|
|
int index = 0;
|
boolean isMatch=false;
|
for (; index < list.size() - head.length; index++) {
|
isMatch=true;
|
for (int j = 0, k = 0; j < head.length; j++, k++) {
|
if (head[j] != list.get(index + k)) {
|
isMatch=false;
|
break;
|
}
|
}
|
if(isMatch) {
|
break;
|
}
|
}
|
|
if (0 < index&&isMatch) {
|
List<Byte> tempList = new ArrayList<Byte>();
|
for(int i=index;i<list.size();i++)
|
{
|
tempList.add(list.get(index));
|
}
|
list=tempList;
|
}
|
|
}
|
@Override
|
public void onHandleResponse() throws Exception {
|
final InputStream stream = getInputStream();
|
if (stream != null && getOptions() != null) {
|
int len=0;
|
while ( (len=getInputStream().read(readBuffer)) != -1) {
|
IHandleMessage handleMessage = getOptions().getHandleMessage();
|
if (handleMessage != null) {
|
byte []bytes = new byte[len];
|
System.arraycopy(readBuffer,0,bytes,0,len);
|
//完整的数据才回调
|
handleMessage.read(bytes);
|
}
|
}
|
}
|
}
|
|
@Override
|
public void sendMsg(byte[] msg) throws Exception {
|
final OutputStream outputStream = getOutStream();
|
if (outputStream != null && getOptions() != null) {
|
try {
|
IHandleMessage handleMessage = getOptions().getHandleMessage();
|
handleMessage.write(handleMessage.write(msg));
|
getOutStream().write(msg);
|
|
} finally {
|
outputStream.flush();
|
}
|
}
|
}
|
|
|
/**
|
* 处理连接状态
|
*/
|
public void onConnectStatus(int status) {
|
ThreadToolUtils.getInstance().runOnUiThread(new Runnable() {
|
@Override
|
public void run() {
|
final List<ConnectStatusListener> list = getOptions().getConnectStatusListener();
|
if (list != null && !list.isEmpty()) {
|
for (ConnectStatusListener listener : list) {
|
switch (status) {
|
case ConnectStatus
|
.CONNECTING:
|
listener.onConnecting();
|
break;
|
case ConnectStatus
|
.CONNECTED:
|
listener.onConnected();
|
break;
|
case ConnectStatus
|
.DISCONNECT:
|
listener.onConnectFailed();
|
break;
|
}
|
}
|
}
|
}
|
});
|
}
|
|
|
private synchronized Socket getSocket() {
|
return new Socket();
|
}
|
|
private InputStream getInputStream() {
|
if (mSocket != null && mSocket.isConnected() && !mSocket.isClosed()) {
|
try {
|
return mSocket.getInputStream();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
return null;
|
}
|
|
|
private OutputStream getOutStream() {
|
if (mSocket != null && mSocket.isConnected() && !mSocket.isClosed()) {
|
try {
|
return mSocket.getOutputStream();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
return null;
|
}
|
|
|
}
|