package com.hdl.sdk.socket.client; import com.hdl.sdk.common.utils.LogUtils; 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.net.SocketAddress; import java.net.StandardSocketOptions; import java.util.ArrayList; import java.util.List; /** * Created by Tong on 2021/9/15. */ public final class TcpClient implements IClient { private SocketOptions socketOptions; private final String ip; private final int port; private Socket mSocket; private final static List tcpClientList = new ArrayList(); /** * 从连接池中找出当前IP及端口的连接客户端 * * @param ipAdderss 连接IP地址 * @param port 连接端口 * @return */ public static TcpClient getTcpClientByIP(String ipAdderss, int port) { for (TcpClient tcpClient : tcpClientList) { if (tcpClient.ip.equals(ipAdderss) && tcpClient.port == port) { return tcpClient; } } return null; } private byte[] readBuffer = new byte[4 * 1024]; private TcpClient(String ip, int port, SocketOptions socketOptions) { this.socketOptions = socketOptions; this.ip = ip; this.port = port; socketOptions.setIp(ip); socketOptions.setPort(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), 3 * 1000); mSocket.setTcpNoDelay(true); mSocket.setReuseAddress(true); // mSocket.setKeepAlive(true); mSocket.setSoTimeout(25 * 1000); tcpClientList.add(this); } @Override public void disconnect() { if (mSocket != null) { try { mSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } @Override public synchronized SocketOptions getOptions() { if (socketOptions == null) { socketOptions = new SocketOptions(); } return socketOptions; } @Override public void onHandleResponse() throws Exception { final InputStream stream = getInputStream(); if (stream != null && getOptions() != null) { while (true) { int len = getInputStream().read(readBuffer); if (len <= 0) { throw new Exception("接收异常,接收数据长度len=" + len); } IHandleMessage handleMessage = getOptions().getHandleMessage(); if (handleMessage != null) { byte[] bytes = new byte[len]; System.arraycopy(readBuffer, 0, bytes, 0, len); //完整的数据才回调 handleMessage.read(bytes, ip); } } } } @Override public void sendMsg(byte[] msg) throws Exception { final OutputStream outputStream = getOutStream(); if (outputStream != null && getOptions() != null) { IHandleMessage handleMessage = getOptions().getHandleMessage(); handleMessage.write(handleMessage.write(msg)); outputStream.write(msg); outputStream.flush(); } } /** * 处理连接状态 */ public void onConnectStatus(int status) { ThreadToolUtils.getInstance().runOnUiThread(new Runnable() { @Override public void run() { final List list = getOptions().getConnectStatusListener(); if (list != null && !list.isEmpty()) { for (ConnectStatusListener listener : list) { switch (status) { case 0: listener.onConnecting(); break; case 1: listener.onConnected(); break; case 2: listener.onConnectFailed(); break; } } } } }); LogUtils.i("TcpClient onConnectStatus status:" + status); } 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; } }